using System;
using System.Collections.Generic;
using System.Windows.Input;
namespace AIStudio.Wpf.DiagramDesigner.Additionals.Commands
{
///
/// 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.
///
public class CanExecuteDelegateCommand : IDelegateCommand
{
#region Constructors
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod)
: this(executeMethod, null, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod)
: this(executeMethod, canExecuteMethod, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod, bool isAutomaticRequeryDisabled)
{
if (executeMethod == null)
{
throw new ArgumentNullException("executeMethod");
}
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
#endregion
#region Public Methods
///
/// Method to determine if the command can be executed
///
public bool CanExecute()
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod();
}
return true;
}
///
/// Execution of the command
///
public void Execute()
{
if (_executeMethod != null)
{
_executeMethod();
}
}
///
///
///
public object Target
{
get
{
if (_executeMethod == null)
return null;
return _executeMethod.Target;
}
}
///
/// Property to enable or disable CommandManager's automatic requery on this command
///
public bool IsAutomaticRequeryDisabled
{
get
{
return _isAutomaticRequeryDisabled;
}
set
{
if (_isAutomaticRequeryDisabled != value)
{
if (value)
{
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
}
else
{
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
}
_isAutomaticRequeryDisabled = value;
}
}
}
///
/// Raises the CanExecuteChaged event
///
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged();
}
///
/// Protected virtual method to raise CanExecuteChanged event
///
protected virtual void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
#endregion
#region ICommand Members
///
/// ICommand.CanExecuteChanged implementation
///
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 _canExecuteMethod = null;
private bool _isAutomaticRequeryDisabled = false;
private List _canExecuteChangedHandlers;
#endregion
}
public class CanExecuteDelegateCommand : IDelegateCommand
{
#region Constructors
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod)
: this(executeMethod, null, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod)
: this(executeMethod, canExecuteMethod, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod, bool isAutomaticRequeryDisabled)
{
if (executeMethod == null)
{
throw new ArgumentNullException("executeMethod");
}
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
#endregion
#region Public Methods
///
/// Method to determine if the command can be executed
///
public bool CanExecute(T1 parameter1)
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod(parameter1);
}
return true;
}
///
/// Execution of the command
///
public void Execute(T1 parameter1)
{
if (_executeMethod != null)
{
_executeMethod(parameter1);
}
}
///
/// Raises the CanExecuteChaged event
///
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged();
}
///
/// Protected virtual method to raise CanExecuteChanged event
///
protected virtual void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
///
/// Property to enable or disable CommandManager's automatic requery on this command
///
public bool IsAutomaticRequeryDisabled
{
get
{
return _isAutomaticRequeryDisabled;
}
set
{
if (_isAutomaticRequeryDisabled != value)
{
if (value)
{
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
}
else
{
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
}
_isAutomaticRequeryDisabled = value;
}
}
}
///
///
///
public object Target
{
get
{
if (_executeMethod == null)
return null;
return _executeMethod.Target;
}
}
#endregion
#region ICommand Members
///
/// ICommand.CanExecuteChanged implementation
///
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);
}
}
public virtual bool CanExecute(object parameter)
{
if (parameter == null || (parameter is object[] && (parameter as object[]).Length < 1))
return false;
if (parameter is object[])
{
object[] parameters = parameter as object[];
// if T is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if ((parameters[0] != null && !typeof(T1).IsAssignableFrom(parameters[0].GetType()))
|| (parameters[0] == null && typeof(T1).IsValueType)
)
{
return false;
}
return CanExecute((T1)parameters[0]);
}
else
{
if (parameter != null && !typeof(T1).IsAssignableFrom(parameter.GetType()))
parameter = null;
return CanExecute((T1)parameter);
}
}
public virtual void Execute(object parameter)
{
//如果T1不允许为空,而parameter参数又为空,则直接返回
if (typeof(T1).IsValueType && (parameter == null || (parameter is object[] && (parameter as object[]).Length < 1)))
return;
if (parameter is object[])
{
object[] parameters = parameter as object[];
// if T1 is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if ((parameters[0] != null && !typeof(T1).IsAssignableFrom(parameters[0].GetType()))
|| (parameters[0] == null && typeof(T1).IsValueType)
)
return;
Execute((T1)parameters[0]);
}
else
{
if (parameter != null && !typeof(T1).IsAssignableFrom(parameter.GetType()))
parameter = null;
Execute((T1)parameter);
}
}
#endregion
#region Data
private readonly Action _executeMethod = null;
private readonly Func _canExecuteMethod = null;
private bool _isAutomaticRequeryDisabled = false;
private List _canExecuteChangedHandlers;
#endregion
}
public class CanExecuteDelegateCommand : IDelegateCommand
{
#region Constructors
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod)
: this(executeMethod, null, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod)
: this(executeMethod, canExecuteMethod, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod, bool isAutomaticRequeryDisabled)
{
if (executeMethod == null)
{
throw new ArgumentNullException("executeMethod");
}
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
#endregion
#region Public Methods
///
/// Method to determine if the command can be executed
///
public bool CanExecute(T1 parameter1, T2 parameter2)
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod(parameter1, parameter2);
}
return true;
}
///
/// Execution of the command
///
public void Execute(T1 parameter1, T2 parameter2)
{
if (_executeMethod != null)
{
_executeMethod(parameter1, parameter2);
}
}
///
/// Raises the CanExecuteChaged event
///
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged();
}
///
/// Protected virtual method to raise CanExecuteChanged event
///
protected virtual void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
///
/// Property to enable or disable CommandManager's automatic requery on this command
///
public bool IsAutomaticRequeryDisabled
{
get
{
return _isAutomaticRequeryDisabled;
}
set
{
if (_isAutomaticRequeryDisabled != value)
{
if (value)
{
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
}
else
{
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
}
_isAutomaticRequeryDisabled = value;
}
}
}
///
///
///
public object Target
{
get
{
if (_executeMethod == null)
return null;
return _executeMethod.Target;
}
}
#endregion
#region ICommand Members
///
/// ICommand.CanExecuteChanged implementation
///
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);
}
}
public virtual bool CanExecute(object parameter)
{
if (parameter == null || !(parameter is object[]) || (parameter as object[]).Length < 2)
return false;
object[] parameters = parameter as object[];
// if T is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if ((parameters[0] != null && !typeof(T1).IsAssignableFrom(parameters[0].GetType()))
|| (parameters[0] == null && typeof(T1).IsValueType)
|| (parameters[1] != null && !typeof(T2).IsAssignableFrom(parameters[1].GetType()))
|| (parameters[1] == null && typeof(T2).IsValueType)
)
{
return false;
}
return CanExecute((T1)parameters[0], (T2)parameters[1]);
}
public virtual void Execute(object parameter)
{
if (parameter == null || !(parameter is object[]) || (parameter as object[]).Length < 2)
return;
object[] parameters = parameter as object[];
// if T is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if ((parameters[0] != null && !typeof(T1).IsAssignableFrom(parameters[0].GetType()))
|| (parameters[0] == null && typeof(T1).IsValueType)
|| (parameters[1] != null && !typeof(T2).IsAssignableFrom(parameters[1].GetType()))
|| (parameters[1] == null && typeof(T2).IsValueType)
)
return;
Execute((T1)parameters[0], (T2)parameters[1]);
}
#endregion
#region Data
private readonly Action _executeMethod = null;
private readonly Func _canExecuteMethod = null;
private bool _isAutomaticRequeryDisabled = false;
private List _canExecuteChangedHandlers;
#endregion
}
public class CanExecuteDelegateCommand : IDelegateCommand
{
#region Constructors
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod)
: this(executeMethod, null, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod)
: this(executeMethod, canExecuteMethod, false)
{
}
///
/// Constructor
///
public CanExecuteDelegateCommand(Action executeMethod, Func canExecuteMethod, bool isAutomaticRequeryDisabled)
{
if (executeMethod == null)
{
throw new ArgumentNullException("executeMethod");
}
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
#endregion
#region Public Methods
///
/// Method to determine if the command can be executed
///
public bool CanExecute(T1 parameter1, T2 parameter2, T3 parameter3)
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod(parameter1, parameter2, parameter3);
}
return true;
}
///
/// Execution of the command
///
public void Execute(T1 parameter1, T2 parameter2, T3 parameter3)
{
if (_executeMethod != null)
{
_executeMethod(parameter1, parameter2, parameter3);
}
}
///
/// Raises the CanExecuteChaged event
///
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged();
}
///
/// Protected virtual method to raise CanExecuteChanged event
///
protected virtual void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
///
/// Property to enable or disable CommandManager's automatic requery on this command
///
public bool IsAutomaticRequeryDisabled
{
get
{
return _isAutomaticRequeryDisabled;
}
set
{
if (_isAutomaticRequeryDisabled != value)
{
if (value)
{
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
}
else
{
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
}
_isAutomaticRequeryDisabled = value;
}
}
}
///
///
///
public object Target
{
get
{
if (_executeMethod == null)
return null;
return _executeMethod.Target;
}
}
#endregion
#region ICommand Members
///
/// ICommand.CanExecuteChanged implementation
///
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);
}
}
public virtual bool CanExecute(object parameter)
{
if (parameter == null || !(parameter is object[]) || (parameter as object[]).Length < 3)
return false;
object[] parameters = parameter as object[];
// if T is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if ((parameters[0] != null && !typeof(T1).IsAssignableFrom(parameters[0].GetType()))
|| (parameters[0] == null && typeof(T1).IsValueType)
|| (parameters[1] != null && !typeof(T2).IsAssignableFrom(parameters[1].GetType()))
|| (parameters[1] == null && typeof(T2).IsValueType)
|| (parameters[2] != null && !typeof(T3).IsAssignableFrom(parameters[2].GetType()))
|| (parameters[2] == null && typeof(T3).IsValueType)
)
{
return false;
}
return CanExecute((T1)parameters[0], (T2)parameters[1], (T3)parameters[2]);
}
public virtual void Execute(object parameter)
{
if (parameter == null || !(parameter is object[]) || (parameter as object[]).Length < 3)
return;
object[] parameters = parameter as object[];
// if T is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if ((parameters[0] != null && !typeof(T1).IsAssignableFrom(parameters[0].GetType()))
|| (parameters[0] == null && typeof(T1).IsValueType)
|| (parameters[1] != null && !typeof(T2).IsAssignableFrom(parameters[1].GetType()))
|| (parameters[1] == null && typeof(T2).IsValueType)
|| (parameters[2] != null && !typeof(T3).IsAssignableFrom(parameters[2].GetType()))
|| (parameters[2] == null && typeof(T3).IsValueType)
)
return;
Execute((T1)parameters[0], (T2)parameters[1], (T3)parameters[2]);
}
#endregion
#region Data
private readonly Action _executeMethod = null;
private readonly Func _canExecuteMethod = null;
private bool _isAutomaticRequeryDisabled = false;
private List _canExecuteChangedHandlers;
#endregion
}
public interface IDelegateCommand : ICommand
{
object Target { get; }
}
///
/// This class contains methods for the CommandManager that help avoid memory leaks by
/// using weak references.
///
internal class CommandManagerHelper
{
internal static void CallWeakReferenceHandlers(List 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 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 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 handlers, EventHandler handler)
{
AddWeakReferenceHandler(ref handlers, handler, -1);
}
internal static void AddWeakReferenceHandler(ref List handlers, EventHandler handler, int defaultListSize)
{
if (handlers == null)
{
handlers = (defaultListSize > 0 ? new List(defaultListSize) : new List());
}
handlers.Add(new WeakReference(handler));
}
internal static void RemoveWeakReferenceHandler(List 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);
}
}
}
}
}
}