WPF Custom Command And Binding
标签:size == handlers gic test eth end mes tostring
1 using System;
2 using System.Collections.Generic;
3 using System.Windows.Input;
4
5 namespace WPF.Commands
6 {
7 ///
8 /// This class allows delegating the commanding logic to methods passed as parameters,
9 /// and enables a View to bind commands to objects that are not part of the element tree.
10 ///
11 public class DelegateCommand : ICommand
12 {
13 #region Constructors
14
15 ///
16 /// Constructor
17 ///
18 public DelegateCommand(Action executeMethod)
19 : this(executeMethod, null, false)
20 {
21 }
22
23 ///
24 /// Constructor
25 ///
26 public DelegateCommand(Action executeMethod, Funcbool> canExecuteMethod)
27 : this(executeMethod, canExecuteMethod, false)
28 {
29 }
30
31 ///
32 /// Constructor
33 ///
34 public DelegateCommand(Action executeMethod, Funcbool> canExecuteMethod, bool isAutomaticRequeryDisabled)
35 {
36 if (executeMethod == null)
37 {
38 throw new ArgumentNullException("executeMethod");
39 }
40
41 _executeMethod = executeMethod;
42 _canExecuteMethod = canExecuteMethod;
43 _isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
44 }
45
46 #endregion
47
48 #region Public Methods
49
50 ///
51 /// Method to determine if the command can be executed
52 ///
53 public bool CanExecute()
54 {
55 if (_canExecuteMethod != null)
56 {
57 return _canExecuteMethod();
58 }
59 return true;
60 }
61
62 ///
63 /// Execution of the command
64 ///
65 public void Execute()
66 {
67 if (_executeMethod != null)
68 {
69 _executeMethod();
70 }
71 }
72
73 ///
74 /// Property to enable or disable CommandManager‘s automatic requery on this command
75 ///
76 public bool IsAutomaticRequeryDisabled
77 {
78 get
79 {
80 return _isAutomaticRequeryDisabled;
81 }
82 set
83 {
84 if (_isAutomaticRequeryDisabled != value)
85 {
86 if (value)
87 {
88 CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
89 }
90 else
91 {
92 CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
93 }
94 _isAutomaticRequeryDisabled = value;
95 }
96 }
97 }
98
99 ///
100 /// Raises the CanExecuteChaged event
101 ///
102 public void RaiseCanExecuteChanged()
103 {
104 OnCanExecuteChanged();
105 }
106
107 ///
108 /// Protected virtual method to raise CanExecuteChanged event
109 ///
110 protected virtual void OnCanExecuteChanged()
111 {
112 CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
113 }
114
115 #endregion
116
117 #region ICommand Members
118
119 ///
120 /// ICommand.CanExecuteChanged implementation
121 ///
122 public event EventHandler CanExecuteChanged
123 {
124 add
125 {
126 if (!_isAutomaticRequeryDisabled)
127 {
128 CommandManager.RequerySuggested += value;
129 }
130 CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
131 }
132 remove
133 {
134 if (!_isAutomaticRequeryDisabled)
135 {
136 CommandManager.RequerySuggested -= value;
137 }
138 CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
139 }
140 }
141
142 ///
143 ///
144 ///
145 ///
146 ///
147 bool ICommand.CanExecute(object parameter)
148 {
149 return CanExecute();
150 }
151
152 ///
153 ///
154 ///
155 ///
156 void ICommand.Execute(object parameter)
157 {
158 Execute();
159 }
160
161 #endregion
162
163 #region Data
164 ///
165 ///
166 ///
167 private readonly Action _executeMethod = null;
168 ///
169 ///
170 ///
171 private readonly Funcbool> _canExecuteMethod = null;
172 ///
173 ///
174 ///
175 private bool _isAutomaticRequeryDisabled = false;
176 ///
177 ///
178 ///
179 private List _canExecuteChangedHandlers;
180
181 #endregion
182 }
183
184 ///
185 /// This class allows delegating the commanding logic to methods passed as parameters,
186 /// and enables a View to bind commands to objects that are not part of the element tree.
187 ///
188 /// Type of the parameter passed to the delegates
189 public class DelegateCommand : ICommand
190 {
191 #region Constructors
192
193 ///
194 /// Constructor
195 ///
196 public DelegateCommand(Action onExecute)
197 : this(onExecute, null, false)
198 {
199 }
200
201 ///
202 /// Constructor
203 ///
204 public DelegateCommand(Action onExecute, Funcbool> canExecute)
205 : this(onExecute, canExecute, false)
206 {
207 }
208
209 ///
210 /// Constructor
211 ///
212 public DelegateCommand(Action onExecute, Funcbool> canExecute, bool isAutomaticRequeryDisabled)
213 {
214 if (onExecute == null)
215 {
216 throw new ArgumentNullException("executeMethod");
217 }
218 _onExecute = onExecute;
219 _canExecute = canExecute;
220 _isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
221 }
222
223 #endregion
224
225 #region Public Methods
226
227 ///
228 /// Method to determine if the command can be executed
229 ///
230 public bool CanExecute(TExecuteParameter parameter)
231 {
232 if (_canExecute != null)
233 {
234 return _canExecute(parameter);
235 }
236 return true;
237 }
238
239 ///
240 /// Execution of the command
241 ///
242 public void Execute(TExecuteParameter parameter)
243 {
244 if (_onExecute != null)
245 {
246 _onExecute(parameter);
247 }
248 }
249
250 ///
251 /// Raises the CanExecuteChaged event
252 ///
253 public void RaiseCanExecuteChanged()
254 {
255 OnCanExecuteChanged();
256 }
257
258 ///
259 /// Protected virtual method to raise CanExecuteChanged event
260 ///
261 protected virtual void OnCanExecuteChanged()
262 {
263 CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
264 }
265
266 ///
267 /// Property to enable or disable CommandManager‘s automatic requery on this command
268 ///
269 public bool IsAutomaticRequeryDisabled
270 {
271 get
272 {
273 return _isAutomaticRequeryDisabled;
274 }
275 set
276 {
277 if (_isAutomaticRequeryDisabled != value)
278 {
279 if (value)
280 {
281 CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
282 }
283 else
284 {
285 CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
286 }
287 _isAutomaticRequeryDisabled = value;
288 }
289 }
290 }
291
292 #endregion
293
294 #region ICommand Members
295
296 ///
297 /// ICommand.CanExecuteChanged implementation
298 ///
299 public event EventHandler CanExecuteChanged
300 {
301 add
302 {
303 if (!_isAutomaticRequeryDisabled)
304 {
305 CommandManager.RequerySuggested += value;
306 }
307 CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
308 }
309 remove
310 {
311 if (!_isAutomaticRequeryDisabled)
312 {
313 CommandManager.RequerySuggested -= value;
314 }
315 CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
316 }
317 }
318
319 ///
320 ///
321 ///
322 ///
323 ///
324 bool ICommand.CanExecute(object parameter)
325 {
326 // if T is of value type and the parameter is not
327 // set yet, then return false if CanExecute delegate
328 // exists, else return true
329 var type = typeof(TExecuteParameter);
330 if (type.IsValueType && type.IsPrimitive)
331 {
332 if (int.TryParse(parameter.ToString(), out int intResult))
333 {
334 return CanExecute((TExecuteParameter)(object)intResult);
335 }
336 }
337
338 if (parameter == null && type.IsValueType)
339 {
340 return (_canExecute == null);
341 }
342 return CanExecute((TExecuteParameter)parameter);
343 }
344
345 ///
346 ///
347 ///
348 ///
349 void ICommand.Execute(object parameter)
350 {
351 Execute((TExecuteParameter)parameter);
352 }
353
354 #endregion
355
356 #region Data
357 ///
358 ///
359 ///
360 private readonly Action _onExecute = null;
361 ///
362 ///
363 ///
364 private readonly Funcbool> _canExecute = null;
365 ///
366 ///
367 ///
368 private bool _isAutomaticRequeryDisabled = false;
369 ///
370 ///
371 ///
372 private List _canExecuteChangedHandlers;
373
374 #endregion
375 }
376
377 ///
378 /// This class contains methods for the CommandManager that help avoid memory leaks by
379 /// using weak references.
380 ///
381 internal class CommandManagerHelper
382 {
383 internal static void CallWeakReferenceHandlers(List handlers)
384 {
385 if (handlers != null)
386 {
387 // Take a snapshot of the handlers before we call out to them since the handlers
388 // could cause the array to me modified while we are reading it.
389
390 EventHandler[] callees = new EventHandler[handlers.Count];
391 int count = 0;
392
393 for (int i = handlers.Count - 1; i >= 0; i--)
394 {
395 WeakReference reference = handlers[i];
396 EventHandler handler = reference.Target as EventHandler;
397 if (handler == null)
398 {
399 // Clean up old handlers that have been collected
400 handlers.RemoveAt(i);
401 }
402 else
403 {
404 callees[count] = handler;
405 count++;
406 }
407 }
408
409 // Call the handlers that we snapshotted
410 for (int i = 0; i )
411 {
412 EventHandler handler = callees[i];
413 handler(null, EventArgs.Empty);
414 }
415 }
416 }
417
418 ///
419 ///
420 ///
421 ///
422 internal static void AddHandlersToRequerySuggested(List handlers)
423 {
424 if (handlers != null)
425 {
426 foreach (WeakReference handlerRef in handlers)
427 {
428 EventHandler handler = handlerRef.Target as EventHandler;
429 if (handler != null)
430 {
431 CommandManager.RequerySuggested += handler;
432 }
433 }
434 }
435 }
436
437 ///
438 ///
439 ///
440 ///
441 internal static void RemoveHandlersFromRequerySuggested(List handlers)
442 {
443 if (handlers != null)
444 {
445 foreach (WeakReference handlerRef in handlers)
446 {
447 EventHandler handler = handlerRef.Target as EventHandler;
448 if (handler != null)
449 {
450 CommandManager.RequerySuggested -= handler;
451 }
452 }
453 }
454 }
455
456 ///
457 ///
458 ///
459 ///
460 ///
461 internal static void AddWeakReferenceHandler(ref List handlers, EventHandler handler)
462 {
463 AddWeakReferenceHandler(ref handlers, handler, -1);
464 }
465
466 ///
467 ///
468 ///
469 ///
470 ///
471 ///
472 internal static void AddWeakReferenceHandler(ref List handlers, EventHandler handler, int defaultListSize)
473 {
474 if (handlers == null)
475 {
476 handlers = (defaultListSize > 0 ? new List(defaultListSize) : new List());
477 }
478
479 handlers.Add(new WeakReference(handler));
480 }
481
482 ///
483 ///
484 ///
485 ///
486 ///
487 internal static void RemoveWeakReferenceHandler(List handlers, EventHandler handler)
488 {
489 if (handlers != null)
490 {
491 for (int i = handlers.Count - 1; i >= 0; i--)
492 {
493 WeakReference reference = handlers[i];
494 EventHandler existingHandler = reference.Target as EventHandler;
495 if ((existingHandler == null) || (existingHandler == handler))
496 {
497 // Clean up old handlers that have been collected
498 // in addition to the handler that is to be removed.
499 handlers.RemoveAt(i);
500 }
501 }
502 }
503 }
504 }
505 }
1 Button Width="60"
2 Height="30"
3 DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
4 Command="{Binding TestCommand}"
5 CommandParameter="123">TestButton>
WPF Custom Command And Binding
标签:size == handlers gic test eth end mes tostring
原文地址:https://www.cnblogs.com/redleaf-me/p/8571288.html
评论