Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
OnEventBehavior.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Linq;
5 using System.Windows;
6 using System.Windows.Data;
7 using System.Windows.Interactivity;
8 
9 using SiliconStudio.Presentation.Core;
10 
11 namespace SiliconStudio.Presentation.Behaviors
12 {
13  /// <summary>
14  /// An abstract behavior that allows to perform actions when an event is raised. It supports both <see cref="RoutedEvent"/> and standard <c>event</c>,
15  /// and allow to catch routed event triggered by any control.
16  /// </summary>
17  public abstract class OnEventBehavior : Behavior<FrameworkElement>
18  {
19  /// <summary>
20  /// Identifies the <see cref="EventName"/> dependency property.
21  /// </summary>
22  public static readonly DependencyProperty EventNameProperty = DependencyProperty.Register("EventName", typeof(string), typeof(OnEventBehavior));
23 
24  /// <summary>
25  /// Identifies the <see cref="EventOwnerType"/> dependency property.
26  /// </summary>
27  public static readonly DependencyProperty EventOwnerTypeProperty = DependencyProperty.Register("EventOwnerType", typeof(Type), typeof(OnEventBehavior));
28 
29  /// <summary>
30  /// Identifies the <see cref="HandleEvent"/> dependency property.
31  /// </summary>
32  public static readonly DependencyProperty HandleEventProperty = DependencyProperty.Register("HandleEvent", typeof(bool), typeof(OnEventBehavior));
33 
34  private readonly RoutedEventHandler routedEventHandler;
35  private AnonymousEventHandler eventHandler;
36  private RoutedEvent routedEvent;
37 
38  protected OnEventBehavior()
39  {
40  routedEventHandler = RoutedEventHandler;
41  }
42 
43  /// <summary>
44  /// Gets or sets the name of the event to handle.
45  /// </summary>
46  public string EventName { get { return (string)GetValue(EventNameProperty); } set { SetValue(EventNameProperty, value); } }
47 
48  /// <summary>
49  /// Gets or sets the type that owns the event when <see cref="EventName"/> describes a <see cref="RoutedEvent"/>.
50  /// </summary>
51  public Type EventOwnerType { get { return (Type)GetValue(EventOwnerTypeProperty); } set { SetValue(EventOwnerTypeProperty, value); } }
52 
53  /// <summary>
54  /// Gets or sets whether to set the event has handled.
55  /// </summary>
56  public bool HandleEvent { get { return (bool)GetValue(HandleEventProperty); } set { SetValue(EventOwnerTypeProperty, value); } }
57 
58  /// <summary>
59  /// Invoked when the monitored event is raised.
60  /// </summary>
61  protected abstract void OnEvent();
62 
63  /// <inheritdoc/>
64  protected override void OnAttached()
65  {
66  if (EventName == null)
67  throw new ArgumentException(string.Format("The EventName property must be set on behavior '{0}'.", GetType().FullName));
68 
69  var eventOwnerType = EventOwnerType ?? AssociatedObject.GetType();
70 
71  RoutedEvent[] routedEvents = EventManager.GetRoutedEvents().Where(evt => evt.Name == EventName && evt.OwnerType.IsAssignableFrom(eventOwnerType)).ToArray();
72 
73  if (routedEvents.Length > 0)
74  {
75  if (routedEvents.Length > 1)
76  throw new NotImplementedException("TODO: several events found, find a way to decide the most relevant one.");
77 
78  routedEvent = routedEvents.First();
79  AssociatedObject.AddHandler(routedEvent, routedEventHandler);
80  }
81  else
82  {
83  var eventInfo = AssociatedObject.GetType().GetEvent(EventName);
84 
85  if (eventInfo == null)
86  throw new InvalidOperationException(string.Format("Impossible to find a valid event named '{0}'.", EventName));
87 
88  eventHandler = AnonymousEventHandler.RegisterEventHandler(eventInfo, AssociatedObject, OnEvent);
89  }
90  }
91 
92  /// <inheritdoc/>
93  protected override void OnDetaching()
94  {
95  if (routedEvent != null)
96  {
97  AssociatedObject.RemoveHandler(routedEvent, routedEventHandler);
98  routedEvent = null;
99  }
100  else if (eventHandler != null)
101  {
102  AnonymousEventHandler.UnregisterEventHandler(eventHandler);
103  eventHandler = null;
104  }
105  }
106 
107  private void RoutedEventHandler(object sender, RoutedEventArgs e)
108  {
109  if (HandleEvent)
110  {
111  e.Handled = true;
112  }
113  OnEvent();
114  }
115  }
116 }
An abstract behavior that allows to perform actions when an event is raised. It supports both RoutedE...