Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
DependencyPropertyWatcher.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.Collections.Generic;
5 using System.ComponentModel;
6 using System.Windows;
7 using System.Windows.Interactivity;
8 
9 using SiliconStudio.Core.Extensions;
10 
11 namespace SiliconStudio.Presentation.Core
12 {
14  {
15  private readonly List<Tuple<DependencyProperty, EventHandler>> handlers = new List<Tuple<DependencyProperty, EventHandler>>();
16  private readonly Dictionary<DependencyProperty, DependencyPropertyDescriptor> descriptors = new Dictionary<DependencyProperty, DependencyPropertyDescriptor>();
17  private FrameworkElement frameworkElement;
18 
19  private bool handlerRegistered;
20 
22  {
23  }
24 
25  public DependencyPropertyWatcher(FrameworkElement attachTo)
26  {
27  Attach(attachTo);
28  }
29 
30  public DependencyObject AssociatedObject { get { return frameworkElement; } }
31 
32  public void Attach(DependencyObject dependencyObject)
33  {
34  if (dependencyObject == null) throw new ArgumentNullException("dependencyObject");
35  if (ReferenceEquals(dependencyObject, frameworkElement))
36  return;
37 
38  if (frameworkElement != null)
39  throw new InvalidOperationException("A dependency object is already attached to this instance of DependencyPropertyWatcher.");
40  frameworkElement = dependencyObject as FrameworkElement;
41 
42  if (frameworkElement == null)
43  throw new ArgumentException("The dependency object to attach to the DependencyPropertyWatcher must be a FrameworkElement.");
44 
45  frameworkElement.Loaded += ElementLoaded;
46  frameworkElement.Unloaded += ElementUnloaded;
47  AttachHandlers();
48  }
49 
50  public void Detach()
51  {
52  frameworkElement.Loaded -= ElementLoaded;
53  frameworkElement.Unloaded -= ElementUnloaded;
54  DetachHandlers();
55  handlers.Clear();
56  frameworkElement = null;
57  }
58 
59  public void RegisterValueChangedHandler(DependencyProperty property, EventHandler handler)
60  {
61  handlers.Add(Tuple.Create(property, handler));
62  if (handlerRegistered)
63  {
64  AttachHandler(property, handler);
65  }
66  }
67 
68  public void UnregisterValueChangedHander(DependencyProperty property, EventHandler handler)
69  {
70  handlers.RemoveWhere(x => x.Item1 == property && x.Item2 == handler);
71  if (handlerRegistered)
72  {
73  DetachHandler(property, handler);
74  }
75  }
76 
77  private void AttachHandlers()
78  {
79  if (!handlerRegistered)
80  {
81  foreach (var handler in handlers)
82  {
83  AttachHandler(handler.Item1, handler.Item2);
84  }
85  handlerRegistered = true;
86  }
87  }
88 
89  private void DetachHandlers()
90  {
91  if (handlerRegistered)
92  {
93  foreach (var handler in handlers)
94  {
95  DetachHandler(handler.Item1, handler.Item2);
96  }
97  handlerRegistered = false;
98  }
99  }
100 
101  private void AttachHandler(DependencyProperty property, EventHandler handler)
102  {
103  if (property == null) throw new ArgumentNullException("property");
104  if (handler == null) throw new ArgumentNullException("handler");
105  if (frameworkElement == null) throw new InvalidOperationException("A dependency object must be attached in order to register a handler.");
106 
107  DependencyPropertyDescriptor descriptor;
108  if (!descriptors.TryGetValue(property, out descriptor))
109  {
110  descriptor = DependencyPropertyDescriptor.FromProperty(property, AssociatedObject.GetType());
111  descriptors.Add(property, descriptor);
112  }
113  descriptor.AddValueChanged(AssociatedObject, handler);
114  }
115 
116  private void DetachHandler(DependencyProperty property, EventHandler handler)
117  {
118  if (property == null) throw new ArgumentNullException("property");
119  if (handler == null) throw new ArgumentNullException("handler");
120  if (frameworkElement == null) throw new InvalidOperationException("A dependency object must be attached in order to unregister a handler.");
121 
122  DependencyPropertyDescriptor descriptor;
123  if (!descriptors.TryGetValue(property, out descriptor))
124  {
125  throw new InvalidOperationException("No handler was previously registered for this dependency property.");
126  }
127  descriptor.RemoveValueChanged(AssociatedObject, handler);
128  }
129 
130  private void ElementLoaded(object sender, RoutedEventArgs e)
131  {
132  AttachHandlers();
133  }
134 
135  private void ElementUnloaded(object sender, RoutedEventArgs e)
136  {
137  DetachHandlers();
138  }
139  }
140 }
void UnregisterValueChangedHander(DependencyProperty property, EventHandler handler)
void RegisterValueChangedHandler(DependencyProperty property, EventHandler handler)