/VMS-Project/VMS.Client/VMS.Client.TrackingSystem/Commands/DelegateCommand.cs
http://rb-vms.googlecode.com/ · C# · 435 lines · 307 code · 52 blank · 76 comment · 48 complexity · 4f31ce6273a157a4f613f6aadcf95dd5 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.Windows;
- using System.Windows.Input;
-
- namespace VMS.Client.TrackingSystem.Commands
- {
- /// <summary>
- /// This class allows delegating the commanding logic to methods passed as parameters,
- /// and enables a View to bind commands to objects that are not part of the element tree.
- /// </summary>
- public class DelegateCommand : ICommand
- {
- #region Constructors
-
- /// <summary>
- /// Constructor
- /// </summary>
- public DelegateCommand(Action executeMethod)
- : this(executeMethod, null, false)
- {
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod)
- : this(executeMethod, canExecuteMethod, false)
- {
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod, bool isAutomaticRequeryDisabled)
- {
- if (executeMethod == null)
- {
- throw new ArgumentNullException("executeMethod");
- }
-
- _executeMethod = executeMethod;
- _canExecuteMethod = canExecuteMethod;
- _isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
- }
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Method to determine if the command can be executed
- /// </summary>
- public bool CanExecute()
- {
- if (_canExecuteMethod != null)
- {
- return _canExecuteMethod();
- }
- return true;
- }
-
- /// <summary>
- /// Execution of the command
- /// </summary>
- public void Execute()
- {
- if (_executeMethod != null)
- {
- _executeMethod();
- }
- }
-
- /// <summary>
- /// Property to enable or disable CommandManager's automatic requery on this command
- /// </summary>
- public bool IsAutomaticRequeryDisabled
- {
- get
- {
- return _isAutomaticRequeryDisabled;
- }
- set
- {
- if (_isAutomaticRequeryDisabled != value)
- {
- if (value)
- {
- CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
- }
- else
- {
- CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
- }
- _isAutomaticRequeryDisabled = value;
- }
- }
- }
-
- /// <summary>
- /// Raises the CanExecuteChaged event
- /// </summary>
- public void RaiseCanExecuteChanged()
- {
- OnCanExecuteChanged();
- }
-
- /// <summary>
- /// Protected virtual method to raise CanExecuteChanged event
- /// </summary>
- protected virtual void OnCanExecuteChanged()
- {
- CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
- }
-
- #endregion
-
- #region ICommand Members
-
- /// <summary>
- /// ICommand.CanExecuteChanged implementation
- /// </summary>
- public event EventHandler CanExecuteChanged
- {
- add
- {
- if (!_isAutomaticRequeryDisabled)
- {
- CommandManager.RequerySuggested += value;
- }
- CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
- }
- remove
- {
- if (!_isAutomaticRequeryDisabled)
- {
- CommandManager.RequerySuggested -= value;
- }
- CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
- }
- }
-
- bool ICommand.CanExecute(object parameter)
- {
- return CanExecute();
- }
-
- void ICommand.Execute(object parameter)
- {
- Execute();
- }
-
- #endregion
-
- #region Data
-
- private readonly Action _executeMethod = null;
- private readonly Func<bool> _canExecuteMethod = null;
- private bool _isAutomaticRequeryDisabled = false;
- private List<WeakReference> _canExecuteChangedHandlers;
-
- #endregion
- }
-
- /// <summary>
- /// This class allows delegating the commanding logic to methods passed as parameters,
- /// and enables a View to bind commands to objects that are not part of the element tree.
- /// </summary>
- /// <typeparam name="T">Type of the parameter passed to the delegates</typeparam>
- public class DelegateCommand<T> : ICommand
- {
- #region Constructors
-
- /// <summary>
- /// Constructor
- /// </summary>
- public DelegateCommand(Action<T> executeMethod)
- : this(executeMethod, null, false)
- {
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
- : this(executeMethod, canExecuteMethod, false)
- {
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod, bool isAutomaticRequeryDisabled)
- {
- if (executeMethod == null)
- {
- throw new ArgumentNullException("executeMethod");
- }
-
- _executeMethod = executeMethod;
- _canExecuteMethod = canExecuteMethod;
- _isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
- }
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Method to determine if the command can be executed
- /// </summary>
- public bool CanExecute(T parameter)
- {
- if (_canExecuteMethod != null)
- {
- return _canExecuteMethod(parameter);
- }
- return true;
- }
-
- /// <summary>
- /// Execution of the command
- /// </summary>
- public void Execute(T parameter)
- {
- if (_executeMethod != null)
- {
- _executeMethod(parameter);
- }
- }
-
- /// <summary>
- /// Raises the CanExecuteChaged event
- /// </summary>
- public void RaiseCanExecuteChanged()
- {
- OnCanExecuteChanged();
- }
-
- /// <summary>
- /// Protected virtual method to raise CanExecuteChanged event
- /// </summary>
- protected virtual void OnCanExecuteChanged()
- {
- CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
- }
-
- /// <summary>
- /// Property to enable or disable CommandManager's automatic requery on this command
- /// </summary>
- public bool IsAutomaticRequeryDisabled
- {
- get
- {
- return _isAutomaticRequeryDisabled;
- }
- set
- {
- if (_isAutomaticRequeryDisabled != value)
- {
- if (value)
- {
- CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
- }
- else
- {
- CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
- }
- _isAutomaticRequeryDisabled = value;
- }
- }
- }
-
- #endregion
-
- #region ICommand Members
-
- /// <summary>
- /// ICommand.CanExecuteChanged implementation
- /// </summary>
- public event EventHandler CanExecuteChanged
- {
- add
- {
- if (!_isAutomaticRequeryDisabled)
- {
- CommandManager.RequerySuggested += value;
- }
- CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
- }
- remove
- {
- if (!_isAutomaticRequeryDisabled)
- {
- CommandManager.RequerySuggested -= value;
- }
- CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
- }
- }
-
- bool ICommand.CanExecute(object parameter)
- {
- // if T is of value type and the parameter is not
- // set yet, then return false if CanExecute delegate
- // exists, else return true
- if (parameter == null &&
- typeof(T).IsValueType)
- {
- return (_canExecuteMethod == null);
- }
- return CanExecute((T)parameter);
- }
-
- void ICommand.Execute(object parameter)
- {
- Execute((T)parameter);
- }
-
- #endregion
-
- #region Data
-
- private readonly Action<T> _executeMethod = null;
- private readonly Func<T, bool> _canExecuteMethod = null;
- private bool _isAutomaticRequeryDisabled = false;
- private List<WeakReference> _canExecuteChangedHandlers;
-
- #endregion
- }
-
- /// <summary>
- /// This class contains methods for the CommandManager that help avoid memory leaks by
- /// using weak references.
- /// </summary>
- internal class CommandManagerHelper
- {
- internal static void CallWeakReferenceHandlers(List<WeakReference> handlers)
- {
- if (handlers != null)
- {
- // Take a snapshot of the handlers before we call out to them since the handlers
- // could cause the array to me modified while we are reading it.
-
- EventHandler[] callees = new EventHandler[handlers.Count];
- int count = 0;
-
- for (int i = handlers.Count - 1; i >= 0; i--)
- {
- WeakReference reference = handlers[i];
- EventHandler handler = reference.Target as EventHandler;
- if (handler == null)
- {
- // Clean up old handlers that have been collected
- handlers.RemoveAt(i);
- }
- else
- {
- callees[count] = handler;
- count++;
- }
- }
-
- // Call the handlers that we snapshotted
- for (int i = 0; i < count; i++)
- {
- EventHandler handler = callees[i];
- handler(null, EventArgs.Empty);
- }
- }
- }
-
- internal static void AddHandlersToRequerySuggested(List<WeakReference> handlers)
- {
- if (handlers != null)
- {
- foreach (WeakReference handlerRef in handlers)
- {
- EventHandler handler = handlerRef.Target as EventHandler;
- if (handler != null)
- {
- CommandManager.RequerySuggested += handler;
- }
- }
- }
- }
-
- internal static void RemoveHandlersFromRequerySuggested(List<WeakReference> handlers)
- {
- if (handlers != null)
- {
- foreach (WeakReference handlerRef in handlers)
- {
- EventHandler handler = handlerRef.Target as EventHandler;
- if (handler != null)
- {
- CommandManager.RequerySuggested -= handler;
- }
- }
- }
- }
-
- internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler)
- {
- AddWeakReferenceHandler(ref handlers, handler, -1);
- }
-
- internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler, int defaultListSize)
- {
- if (handlers == null)
- {
- handlers = (defaultListSize > 0 ? new List<WeakReference>(defaultListSize) : new List<WeakReference>());
- }
-
- handlers.Add(new WeakReference(handler));
- }
-
- internal static void RemoveWeakReferenceHandler(List<WeakReference> handlers, EventHandler handler)
- {
- if (handlers != null)
- {
- for (int i = handlers.Count - 1; i >= 0; i--)
- {
- WeakReference reference = handlers[i];
- EventHandler existingHandler = reference.Target as EventHandler;
- if ((existingHandler == null) || (existingHandler == handler))
- {
- // Clean up old handlers that have been collected
- // in addition to the handler that is to be removed.
- handlers.RemoveAt(i);
- }
- }
- }
- }
- }
- }