Browse Source

Added Raised observable to RoutedEvent.

Similar to PerspexProperty.Changed observable. Make AddClassHandler
methods use this.
pull/422/head
Steven Kirk 10 years ago
parent
commit
be8079137d
  1. 2
      src/Perspex.Interactivity/Interactive.cs
  2. 70
      src/Perspex.Interactivity/RoutedEvent.cs

2
src/Perspex.Interactivity/Interactive.cs

@ -175,7 +175,7 @@ namespace Perspex.Interactivity
{
Contract.Requires<ArgumentNullException>(e != null);
e.RoutedEvent.InvokeClassHandlers(this, e);
e.RoutedEvent.InvokeRaised(this, e);
List<EventSubscription> subscriptions;

70
src/Perspex.Interactivity/RoutedEvent.cs

@ -2,8 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reactive.Subjects;
using System.Reflection;
using System.Runtime.ExceptionServices;
@ -19,7 +18,7 @@ namespace Perspex.Interactivity
public class RoutedEvent
{
private readonly List<ClassEventSubscription> _subscriptions = new List<ClassEventSubscription>();
private Subject<Tuple<object, RoutedEventArgs>> _raised = new Subject<Tuple<object, RoutedEventArgs>>();
public RoutedEvent(
string name,
@ -62,6 +61,8 @@ namespace Perspex.Interactivity
private set;
}
public IObservable<Tuple<object, RoutedEventArgs>> Raised => _raised;
public static RoutedEvent<TEventArgs> Register<TOwner, TEventArgs>(
string name,
RoutingStrategies routingStrategy)
@ -83,27 +84,24 @@ namespace Perspex.Interactivity
return new RoutedEvent<TEventArgs>(name, routingStrategy, ownerType);
}
public void AddClassHandler(Type type, EventHandler<RoutedEventArgs> handler, RoutingStrategies routes)
public IDisposable AddClassHandler(
Type targetType,
EventHandler<RoutedEventArgs> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false)
{
_subscriptions.Add(new ClassEventSubscription
return Raised.Subscribe(args =>
{
TargetType = type,
Handler = handler,
Routes = routes,
});
}
var sender = args.Item1;
var e = args.Item2;
internal void InvokeClassHandlers(object sender, RoutedEventArgs e)
{
foreach (var sub in _subscriptions)
{
if (sub.TargetType.GetTypeInfo().IsAssignableFrom(sender.GetType().GetTypeInfo()) &&
((e.Route == RoutingStrategies.Direct) || (e.Route & sub.Routes) != 0) &&
(!e.Handled || sub.AlsoIfHandled))
if (targetType.GetTypeInfo().IsAssignableFrom(sender.GetType().GetTypeInfo()) &&
((e.Route == RoutingStrategies.Direct) || (e.Route & routes) != 0) &&
(!e.Handled || handledEventsToo))
{
try
{
sub.Handler.DynamicInvoke(sender, e);
handler.DynamicInvoke(sender, e);
}
catch (TargetInvocationException ex)
{
@ -111,12 +109,12 @@ namespace Perspex.Interactivity
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
}
}
});
}
private class ClassEventSubscription : EventSubscription
internal void InvokeRaised(object sender, RoutedEventArgs e)
{
public Type TargetType { get; set; }
_raised.OnNext(Tuple.Create(sender, e));
}
}
@ -130,26 +128,24 @@ namespace Perspex.Interactivity
Contract.Requires<ArgumentNullException>(ownerType != null);
}
public void AddClassHandler<TTarget>(
public IDisposable AddClassHandler<TTarget>(
Func<TTarget, Action<TEventArgs>> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble)
where TTarget : class
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false)
where TTarget : class, IInteractive
{
AddClassHandler(typeof(TTarget), (s, e) => ClassHandlerAdapter<TTarget>(s, e, handler), routes);
}
EventHandler<RoutedEventArgs> adapter = (sender, e) =>
{
var target = sender as TTarget;
var args = e as TEventArgs;
private static void ClassHandlerAdapter<TTarget>(
object sender,
RoutedEventArgs e,
Func<TTarget, Action<TEventArgs>> handler) where TTarget : class
{
var target = sender as TTarget;
var args = e as TEventArgs;
if (target != null && args != null)
{
handler(target)(args);
}
};
if (target != null && args != null)
{
handler(target)(args);
}
return AddClassHandler(typeof(TTarget), adapter, routes, handledEventsToo);
}
}
}

Loading…
Cancel
Save