using System;
using System.Collections.Generic;
using System.Windows.Input; namespace WPF.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, );
}
remove
{
if (!_isAutomaticRequeryDisabled)
{
CommandManager.RequerySuggested -= value;
}
CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
}
} /// <summary>
///
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
bool ICommand.CanExecute(object parameter)
{
return CanExecute();
} /// <summary>
///
/// </summary>
/// <param name="parameter"></param>
void ICommand.Execute(object parameter)
{
Execute();
} #endregion #region Data
/// <summary>
///
/// </summary>
private readonly Action _executeMethod = null;
/// <summary>
///
/// </summary>
private readonly Func<bool> _canExecuteMethod = null;
/// <summary>
///
/// </summary>
private bool _isAutomaticRequeryDisabled = false;
/// <summary>
///
/// </summary>
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="TExecuteParameter">Type of the parameter passed to the delegates</typeparam>
public class DelegateCommand<TExecuteParameter> : ICommand
{
#region Constructors /// <summary>
/// Constructor
/// </summary>
public DelegateCommand(Action<TExecuteParameter> onExecute)
: this(onExecute, null, false)
{
} /// <summary>
/// Constructor
/// </summary>
public DelegateCommand(Action<TExecuteParameter> onExecute, Func<TExecuteParameter, bool> canExecute)
: this(onExecute, canExecute, false)
{
} /// <summary>
/// Constructor
/// </summary>
public DelegateCommand(Action<TExecuteParameter> onExecute, Func<TExecuteParameter, bool> canExecute, bool isAutomaticRequeryDisabled)
{
if (onExecute == null)
{
throw new ArgumentNullException("executeMethod");
}
_onExecute = onExecute;
_canExecute = canExecute;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
} #endregion #region Public Methods /// <summary>
/// Method to determine if the command can be executed
/// </summary>
public bool CanExecute(TExecuteParameter parameter)
{
if (_canExecute != null)
{
return _canExecute(parameter);
}
return true;
} /// <summary>
/// Execution of the command
/// </summary>
public void Execute(TExecuteParameter parameter)
{
if (_onExecute != null)
{
_onExecute(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, );
}
remove
{
if (!_isAutomaticRequeryDisabled)
{
CommandManager.RequerySuggested -= value;
}
CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
}
} /// <summary>
///
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
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
var type = typeof(TExecuteParameter);
if (type.IsValueType && type.IsPrimitive)
{
if (int.TryParse(parameter.ToString(), out int intResult))
{
return CanExecute((TExecuteParameter)(object)intResult);
}
} if (parameter == null && type.IsValueType)
{
return (_canExecute == null);
}
return CanExecute((TExecuteParameter)parameter);
} /// <summary>
///
/// </summary>
/// <param name="parameter"></param>
void ICommand.Execute(object parameter)
{
Execute((TExecuteParameter)parameter);
} #endregion #region Data
/// <summary>
///
/// </summary>
private readonly Action<TExecuteParameter> _onExecute = null;
/// <summary>
///
/// </summary>
private readonly Func<TExecuteParameter, bool> _canExecute = null;
/// <summary>
///
/// </summary>
private bool _isAutomaticRequeryDisabled = false;
/// <summary>
///
/// </summary>
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 = ; for (int i = handlers.Count - ; i >= ; 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 = ; i < count; i++)
{
EventHandler handler = callees[i];
handler(null, EventArgs.Empty);
}
}
} /// <summary>
///
/// </summary>
/// <param name="handlers"></param>
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;
}
}
}
} /// <summary>
///
/// </summary>
/// <param name="handlers"></param>
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;
}
}
}
} /// <summary>
///
/// </summary>
/// <param name="handlers"></param>
/// <param name="handler"></param>
internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler)
{
AddWeakReferenceHandler(ref handlers, handler, -);
} /// <summary>
///
/// </summary>
/// <param name="handlers"></param>
/// <param name="handler"></param>
/// <param name="defaultListSize"></param>
internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler, int defaultListSize)
{
if (handlers == null)
{
handlers = (defaultListSize > ? new List<WeakReference>(defaultListSize) : new List<WeakReference>());
} handlers.Add(new WeakReference(handler));
} /// <summary>
///
/// </summary>
/// <param name="handlers"></param>
/// <param name="handler"></param>
internal static void RemoveWeakReferenceHandler(List<WeakReference> handlers, EventHandler handler)
{
if (handlers != null)
{
for (int i = handlers.Count - ; i >= ; 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);
}
}
}
}
}
}
 <Button Width="60"
Height="30"
DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
Command="{Binding TestCommand}"
CommandParameter="123">Test</Button>

WPF Custom Command And Binding的更多相关文章

  1. [WPF]如何调试Data Binding

    前言 在WPF开发中,将ViewModel中对象绑定到UI上时,会出现明明已经将数据对象Binding到UI,但是UI上就是不显示等等的问题.这篇博客将介绍WPF Data Binding相关的内容, ...

  2. ClassLibary和WPF User Control LIbary和WPF Custom Control Libary的异同

    说来惭愧,接触WPF这么长时间了,今天在写自定义控件时遇到一个问题:运行界面中并没有显示自定义控件,经调试发现原来没有加载Themes中的Generic.xaml. 可是为什么在其他solution中 ...

  3. Typora + PicGo-Core + Custom Command 实现上传图片到图床

    教程参考 Typora+PicGo-Core(command line)+Gitee实现图片上传到图床 主要借鉴 picgo 操作命令 Typora + PicGo + Gitee 实现图片自动上传到 ...

  4. silverlight wpf DataTemplate Command binding

    <Grid x:Name="LayoutRoot" Background="White"> <CommonControl:NoapDataGr ...

  5. wpf custom control

    最近在做WPF,记录一下自定义控件的制作过程,源码请点击:源码. 1.目标 实现一个如图所示的可增减的数字框: 2.先画Template 可以在Generic.xaml中画,也可以用MergedDic ...

  6. WPF 定义Command

    直接上代码: public class LoginDelegateCommand : ICommand { private Action _execute; private Predicate< ...

  7. Zara带你快速入门WPF(4)---Command与功能区控件

    前言:许多数据驱动的应用程序都包含菜单和工具栏或功能区控件,允许用户控制操作,在WPF中,也可以使用功能区控件,所以这里介绍菜单和功能区控件. 一.菜单控件 在WPF中,菜单很容易使用Menu和Men ...

  8. WPF 自定义Command

    无参Command: internal class DelegateCommand : ICommand { private readonly Action _execute; private rea ...

  9. Recommended Practices for WPF Custom Control Developers

    I have always found that there isn’t enough documentation about Custom Control development in WPF. M ...

随机推荐

  1. 访问者模式和php实现

    访问者模式: 表示作用于某个对象结构中的各个元素的操作.它使你可以在不改变各个元素类的前提下定义作用于这些元素的操作. 角色: 1)抽象访问者:为该对象结构中具体元素角色声明一个访问操作接口.该操作接 ...

  2. BBS项目需求分析及表格创建

    1.项目需求分析 1.登陆功能(基于ajax,图片验证码) 2.注册功能(基于ajax,基于forms验证) 3.博客首页 4.个人站点 5.文章详情 6.点赞,点踩 7.评论 --根评论 --子评论 ...

  3. Oracle数据仓库创建教程

    Oracle数据仓库创建教程.如何创建一个数据仓库,创建实例,以为毕业设计要求,最近开始Oracle的数仓建模实践,详细记录了图形界面下的 Oracle database 12C 数据仓库创建过程. ...

  4. arcgis jsapi接口入门系列(10):图形高亮

    jsapi也有提供高亮的实现接口,但这里没用,而用的是一种改变图形(graphic)样式的思路 本文实现效果是:地图有多个面图形,当鼠标移动到面的上方,面高亮显示,鼠标移出后高亮解除 初始化 //高亮 ...

  5. Json字符串转excel表格文件

    假如我们有一段json串,该json串是由一系列结构相同的数据集合组成,如下: { "data": [ { "groupId": "com.test. ...

  6. 洛谷 P2617 Dynamic Ranking

    题目描述 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤ ...

  7. WPF中播放视频音频

    首先要在WPF中播放视频和音频,我们就需要用到MediaElement控件,下面我们示例播放音频和视频. 用MediaElement播放音频: 第一步:将你需要播放的音频(mp3)放在你WPF项目的D ...

  8. 解决Genymotion2.8.1在拖动安装APK文件出现ARMtranslate错误

    转载文章:http://blog.csdn.net/solo_talk/article/details/68488129 在新版本的genymotion中,我们拖动安装APK文件的时候会出现一个问题, ...

  9. Spring框架针对dao层的jdbcTemplate操作crud之delete删除数据库操作 Spring相关Jar包下载

    首先,找齐Spring框架中IoC功能.aop功能.JdbcTemplate功能所需的jar包,当前13个Jar包 1.Spring压缩包中的四个核心JAR包,实现IoC控制反转的根据xml配置文件或 ...

  10. ViewController的lifecycle和autolayout