WPF命令-绑定don';不管用,直接打电话就行.为什么

本文关键字:打电话 为什么 不管 绑定 命令 don WPF | 更新日期: 2023-09-27 18:08:34


这个问题只是为了理解。只要应用程序正常工作,IDE就可以告诉我不存在的错误。


我正在使用MVVM模式开发一个c#WPF应用程序;数据和CCD_ 1。

但是,我注意到,当我使用绑定绑定到Command时,该命令不会执行,但是,IDE或调试输出中都不会显示任何错误。

例如:

Command="{Binding MyCommand}"
<!-- Or -->
Command="{Binding cmd:Commands.MyCommand}"

然而,仅仅写

Command="cmd:Command.MyCommand"

虽然XAML编辑器显示了一个错误,说找不到该命令,但它运行得很好。

为什么会这样?

WPF命令-绑定don';不管用,直接打电话就行.为什么

您需要绑定到类型为ICommand的属性。此属性将使用您的函数实现RelayCommand

RelayCommand的默认实现如下:

public class RelayCommand : ICommand
{
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    private readonly Action methodToExecute;
    private readonly Func<bool> canExecuteEvaluator;
    public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator)
    {
        this.methodToExecute = methodToExecute;
        this.canExecuteEvaluator = canExecuteEvaluator;
    }
    public RelayCommand(Action methodToExecute)
        : this(methodToExecute, null)
    {
    }
    public bool CanExecute(object parameter)
    {
        if (canExecuteEvaluator == null)
        {
            return true;
        }
        bool result = canExecuteEvaluator.Invoke();
        return result;
    }
    public void Execute(object parameter)
    {
        methodToExecute.Invoke();
    }
}

在ViewModel中,您需要使用OnClick函数实现ICommand类型的属性:

public ICommand MyCommand
{
    get
    {
        return new RelayCommand(() =>
        {
            doSomething();
        });
    }
}

现在,您可以在运行时将视图的Button命令动态绑定到ICommand:

Command="{Binding MyCommand}"

此外,请记住Command="cmd:Command.MyCommand"是一个静态实现。

这里是我使用的relayCommand:

  public sealed class RelayCommand : ICommand
{
    #region Fields
    readonly Action<object> _action;
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;
    #endregion  Fields
    #region Constructors
    public RelayCommand(Action<object> action)
    {
        if (action != null)
            _action = action;
    }
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
        _execute = execute;
        _canExecute = canExecute;
    }
    #endregion Constructors
    #region ICommand Members
    public void Execute(object parameter)
    {
        if (_execute != null)
            _execute(parameter);
        else
        {
            _action(parameter ?? "Command parameter is null!");
        }
    }
    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute(parameter);
    }
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    #endregion
}

您需要的是在viewModel命令中实现,您将能够像这样绑定它:

Command="{Binding MyCommand}"

编辑就我而言,我更喜欢使用两个库——交互和交互。在他们的帮助下,很容易将所有事件绑定到viewModel。例如:

xaml:

<i:Interaction.Triggers>
     <i:EventTrigger EventName="Click">
           <ei:CallMethodAction TargetObject="{Binding}" MethodName="OnClick"/>
     </i:EventTrigger>                
</i:Interaction.Triggers>

和视图型号:

public void OnClick(object sender, RoutedEventArgs e)
{
    //your code
}