View Code
1 //===================================================================================
2 // Microsoft patterns & practices
3 // Composite Application Guidance for Windows Presentation Foundation and Silverlight
4 //===================================================================================
5 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
7 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
8 // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
9 // FITNESS FOR A PARTICULAR PURPOSE.
10 //===================================================================================
11 // The example companies, organizations, products, domain names,
12 // e-mail addresses, logos, people, places, and events depicted
13 // herein are fictitious. No association with any real company,
14 // organization, product, domain name, email address, logo, person,
15 // places, or events is intended or should be inferred.
16 //===================================================================================
17 using System;
18 using System.Collections.Generic;
19 using System.Windows.Threading;
20 using System.Windows;
21
22 namespace Microsoft.Practices.Prism.Commands
23 {
24 /// <summary>
25 /// Handles management and dispatching of EventHandlers in a weak way.
26 /// </summary>
27 internal static class WeakEventHandlerManager
28 {
29 ///<summary>
30 /// Invokes the handlers
31 ///</summary>
32 ///<param name="sender"></param>
33 ///<param name="handlers"></param>
34 public static void CallWeakReferenceHandlers(
object sender, List<WeakReference>
handlers)
35 {
36 if (handlers !=
null)
37 {
38 // Take a snapshot of the handlers before we call out to them since the handlers
39 // could cause the array to me modified while we are reading it.
40 EventHandler[] callees =
new EventHandler[handlers.Count];
41 int count =
0;
42
43 //Clean up handlers
44 count =
CleanupOldHandlers(handlers, callees, count);
45
46 // Call the handlers that we snapshotted
47 for (
int i =
0; i < count; i++
)
48 {
49 CallHandler(sender, callees[i]);
50 }
51 }
52 }
53
54 private static void CallHandler(
object sender, EventHandler eventHandler)
55 {
56 DispatcherProxy dispatcher =
DispatcherProxy.CreateDispatcher();
57
58 if (eventHandler !=
null)
59 {
60 if (dispatcher !=
null && !
dispatcher.CheckAccess())
61 {
62 dispatcher.BeginInvoke((Action<
object, EventHandler>
)CallHandler, sender, eventHandler);
63 }
64 else
65 {
66 eventHandler(sender, EventArgs.Empty);
67 }
68 }
69 }
70
71 /// <summary>
72 /// Hides the dispatcher mis-match between Silverlight and .Net, largely so code reads a bit easier
73 /// </summary>
74 private class DispatcherProxy
75 {
76 Dispatcher innerDispatcher;
77
78 private DispatcherProxy(Dispatcher dispatcher)
79 {
80 innerDispatcher =
dispatcher;
81 }
82
83 public static DispatcherProxy CreateDispatcher()
84 {
85 DispatcherProxy proxy =
null;
86 #if SILVERLIGHT
87 if (Deployment.Current ==
null)
88 return null;
89
90 proxy =
new DispatcherProxy(Deployment.Current.Dispatcher);
91 #else
92 if (Application.Current ==
null)
93 return null;
94
95 proxy =
new DispatcherProxy(Application.Current.Dispatcher);
96 #endif
97 return proxy;
98
99 }
100
101 public bool CheckAccess()
102 {
103 return innerDispatcher.CheckAccess();
104 }
105
106 [System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.Portability",
"CA1903:UseOnlyApiFromTargetedFramework", MessageId =
"System.Windows.Threading.Dispatcher.#BeginInvoke(System.Delegate,System.Windows.Threading.DispatcherPriority,System.Object[])")]
107 public DispatcherOperation BeginInvoke(Delegate method,
params Object[] args)
108 {
109 #if SILVERLIGHT
110 return innerDispatcher.BeginInvoke(method, args);
111 #else
112 return innerDispatcher.BeginInvoke(method, DispatcherPriority.Normal, args);
113 #endif
114 }
115 }
116
117 private static int CleanupOldHandlers(List<WeakReference> handlers, EventHandler[] callees,
int count)
118 {
119 for (
int i = handlers.Count -
1; i >=
0; i--
)
120 {
121 WeakReference reference =
handlers[i];
122 EventHandler handler = reference.Target
as EventHandler;
123 if (handler ==
null)
124 {
125 // Clean up old handlers that have been collected
126 handlers.RemoveAt(i);
127 }
128 else
129 {
130 callees[count] =
handler;
131 count++
;
132 }
133 }
134 return count;
135 }
136
137 ///<summary>
138 /// Adds a handler to the supplied list in a weak way.
139 ///</summary>
140 ///<param name="handlers">Existing handler list. It will be created if null.</param>
141 ///<param name="handler">Handler to add.</param>
142 ///<param name="defaultListSize">Default list size.</param>
143 public static void AddWeakReferenceHandler(
ref List<WeakReference> handlers, EventHandler handler,
int defaultListSize)
144 {
145 if (handlers ==
null)
146 {
147 handlers = (defaultListSize >
0 ?
new List<WeakReference>(defaultListSize) :
new List<WeakReference>
());
148 }
149
150 handlers.Add(
new WeakReference(handler));
151 }
152
153 ///<summary>
154 /// Removes an event handler from the reference list.
155 ///</summary>
156 ///<param name="handlers">Handler list to remove reference from.</param>
157 ///<param name="handler">Handler to remove.</param>
158 public static void RemoveWeakReferenceHandler(List<WeakReference>
handlers, EventHandler handler)
159 {
160 if (handlers !=
null)
161 {
162 for (
int i = handlers.Count -
1; i >=
0; i--
)
163 {
164 WeakReference reference =
handlers[i];
165 EventHandler existingHandler = reference.Target
as EventHandler;
166 if ((existingHandler ==
null) || (existingHandler ==
handler))
167 {
168 // Clean up old handlers that have been collected
169 // in addition to the handler that is to be removed.
170 handlers.RemoveAt(i);
171 }
172 }
173 }
174 }
175 }
176 }
转载于:https://www.cnblogs.com/easy5weikai/archive/2012/12/12/2813979.html
相关资源:Graphpad-Prism5中文教程