03.Command

参考JusterZhu视频和文档,ppt文档基本全抄

Command

日常开发中必不可少会用到命令,比如button自带了Command和CommandParameter属性。细心的小伙可能会发现并不是所有的控件都自带这样的属性,那么如何让“万物皆可Command”呢?

  1. 通常使用System.Windows.Interactivity.dll提供的Interaction对象,它的本质是附加属性可以附加到wpf所有的控件之上,因为所有wpf控件的基类都是DependencyObject的。

  2. 避免版本问题,推荐使用Microsoft.Xaml.Behaviors.Wpf 该组件支持.net5
    https://github.com/Microsoft/XamlBehaviorsWpf

如何使用Interactivity 对象?

  1. Install-Package Microsoft.Xaml.Behaviors.Wpf -Version 1.1.31;
  2. XAML文件中引入 xmlns:i=http://schemas.microsoft.com/xaml/behaviors;
  3. 任意控件标签中添加Interaction.Triggers;
  4. 指定EventTrigger的名称,每个控件都会自带一些事件填写该名称即可;
  5. 指定InvokeCommandAction最终需要执行的命令;
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <Button Width="120" Height="60"
            Margin="10" Command="{Binding TestCommand}"
            Content="click me"></Button>
    <Rectangle Width="120" Height="60"
               Fill="SeaGreen"></Rectangle>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDown">
            <i:InvokeCommandAction Command="{Binding TestCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</StackPanel>
internal class MainViewModel
{
    public ICommand TestCommand { get; set; }
    public MainViewModel() 
    {
        TestCommand = new RelayCommand(TestCallBack);
    }

    private void TestCallBack()
    {
        Application.Current.Dispatcher.Invoke(() => 
        {
            MessageBox.Show("hello world.");
        });
    }
}
public class RelayCommand : ICommand
{
    #region 字段
    readonly Func<bool> _canExecute;
    readonly Action _execute;
    #endregion

    #region 构造函数
    public RelayCommand(Action execute) : this(execute, null)
    {
        
    }

    public RelayCommand(Action execute, Func<bool> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }
        _execute = execute;
        _canExecute = canExecute;
    }
    #endregion

    #region ICommand的成员

    public event EventHandler CanExecuteChanged
    {
        add
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested += value;
        }

        remove
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested -= value;
        }
    }

    [DebuggerStepThrough]

    public Boolean CanExecute(Object parameter)
    {
        return _canExecute == null ? true : _canExecute();
    }

    public void Execute(Object parameter)
    {
        _execute();
    }

    #endregion
}

/// <summary>
/// A command whose sole purpose is to 
/// relay its functionality to other
/// objects by invoking delegates. The
/// default return value for the CanExecute
/// method is 'true'.
/// </summary>
public class RelayCommand<T> : ICommand
{
    #region Constructors

    public RelayCommand(Action<T> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion // Constructors

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute((T)parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested += value;
        }
        remove
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested -= value;
        }
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

    #endregion // ICommand Members

    #region Fields

    readonly Action<T> _execute = null;
    readonly Predicate<T> _canExecute = null;

    #endregion // Fields
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值