本文介绍了ICommand的CanExecute方法如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过一些实现 ICommand 的示例,对我来说,以下方法是最简单的:

I've looked at some examples of implementing ICommand and to me the following way is the simplest:

class Command : ICommand {
    public Func<object, bool> CanDo { get; set; }
    public Action<object> Do { get; set; }

    public event EventHandler CanExecuteChanged {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public Command(Func<object, bool> CanDo, Action<object> Do) {
        this.CanDo = CanDo;
        this.Do = Do;
    }

    public bool CanExecute(object parameter) => CanDo(parameter);
    public void Execute(object parameter) => Do(parameter);
}

这就是我在测试应用程序中实现的方式.除了 Command 类之外,我还有以下类:

and that's how I've implemented in my test app. In addition to the Command class I've the following class:

class Person : INotifyPropertyChanged {

    string firstName, lastName, enabled;

    public string FirstName {
        get => firstName;
        set { firstName = value; Changed();}
    }

    public string LastName {
        get => lastName;
        set { lastName = value; Changed(); }
    }

    public string Enabled {
        get => enabled;
        set { enabled = value;  Changed(); }
    }

    public Command MyCommand { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;

    public Person() {
        MyCommand = new Command(CanDo, Do);
    }

    void Changed(string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

    bool CanDo(object para) {
        if (FirstName == "test" && LastName == "test") {
            Enabled = "true";
            //Changed("Enabled");
            return true;
        }
        else {
            Enabled = "false";
            //Changed("Enabled");
            return false;
        }
    }

    void Do(object para) {
        FirstName = "first";
        LastName = "last";
    }
}

xaml 中的这些是

<Window ...>
    <Window.Resources>
        <local:Person x:Key="person"/>
    </Window.Resources>      
    <Grid DataContext="{StaticResource person}">
        <StackPanel>
            <TextBox Text="{Binding FirstName}"/>
            <TextBox Text="{Binding LastName}"/>
            <TextBlock Text="{Binding FirstName}"/>
            <TextBlock Text="{Binding LastName}"/>

            <Button Content="Click" Command="{Binding Path=MyCommand}"/>
            <Label Content="{Binding Enabled}"/>
        </StackPanel>         
    </Grid>
</Window>

启动应用程序后,如果我在 setter Setter 中调用 Changed(),则我尝试在这些 TextBox 中键入的内容都会立即删除.已启用.如果我注释掉 setter 中的 Changed()并取消注释 bool CanDo(object para)中的两个 Changed("Enabled")可以正常工作!

After launching the app, whatever I try to type in those TextBox gets deleted instantly if I call Changed() in the setter of Enabled. If I comment out the Changed() in setter and uncomment two Changed("Enabled") in bool CanDo(object para) it works as expected!

不应在 setter 中调用一次 Changed(),等同于在中调用这两个 Changed("Enabled")> bool CanDo(object para)?

Shouldn't calling the Changed() once in setter be equivalent to those two Changed("Enabled") call in bool CanDo(object para)?

推荐答案

您在已更改:

void Changed([System.Runtime.CompilerServices.CallerMemberName]string name = "") => 
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

这将获取调用属性名称,因此您不必调用设置器中的 Changed("Enabled").只需调用 Changed().

This obtains the calling property name so you don't have to call Changed("Enabled") but simply Changed() in the setter.

这篇关于ICommand的CanExecute方法如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 16:52