// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Interactivity { using System; using System.Linq.Expressions; using System.Reflection; public enum RoutingStrategy { Tunnel, Bubble, Direct, } public class RoutedEvent { public RoutedEvent( string name, RoutingStrategy routingStrategy, Type eventArgsType, Type ownerType) { Contract.Requires(name != null); Contract.Requires(eventArgsType != null); Contract.Requires(ownerType != null); Contract.Requires(typeof(RoutedEventArgs).GetTypeInfo().IsAssignableFrom(eventArgsType.GetTypeInfo())); Contract.Requires(typeof(IInteractive).GetTypeInfo().IsAssignableFrom(ownerType.GetTypeInfo())); this.EventArgsType = eventArgsType; this.Name = name; this.OwnerType = ownerType; this.RoutingStrategy = routingStrategy; } public event EventHandler Raised; public Type EventArgsType { get; private set; } public string Name { get; private set; } public Type OwnerType { get; private set; } public RoutingStrategy RoutingStrategy { get; private set; } public static RoutedEvent Register( string name, RoutingStrategy routingStrategy) where TOwner : IInteractive where TEventArgs : RoutedEventArgs { Contract.Requires(name != null); return new RoutedEvent(name, routingStrategy, typeof(TOwner)); } public static RoutedEvent Register( string name, RoutingStrategy routingStrategy, Type ownerType) where TEventArgs : RoutedEventArgs { Contract.Requires(name != null); return new RoutedEvent(name, routingStrategy, ownerType); } internal void InvokeRaised(object sender, RoutedEventArgs e) { if (this.Raised != null) { this.Raised(sender, e); } } } public class RoutedEvent : RoutedEvent where TEventArgs : RoutedEventArgs { public RoutedEvent(string name, RoutingStrategy routingStrategy, Type ownerType) : base(name, routingStrategy, typeof(TEventArgs), ownerType) { Contract.Requires(name != null); Contract.Requires(ownerType != null); Contract.Requires(typeof(IInteractive).GetTypeInfo().IsAssignableFrom(ownerType.GetTypeInfo())); } public void AddClassHandler(Func> handler) where TTarget : class { this.Raised += (s, e) => { var target = s as TTarget; var args = e as TEventArgs; if (target != null) { handler(target)(args); } }; } } }