如何使用 Prism 6 正确触发 CanExecute [英] How to make the CanExecute trigger properly using Prism 6

查看:33
本文介绍了如何使用 Prism 6 正确触发 CanExecute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型

public class Irritant : BindableBase
{
    private short _id;
    private string _name;
    private string _description;

    public short Id
    {
        get { return _id; }
        set { SetProperty(ref _id, value); }
    }

    public string Name
    {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }

    public string Description
    {
        get { return _description; }
        set { SetProperty(ref _description, value); }
    }


    public Irritant()
    {
        Id = 0;
        Name = "";
        Description = "";       
    }
}

然后我的 ViewModel 有两个版本

Then my ViewModel with two versions

public class IrritantViewModel : BindableBase
{
    private IrritantDb db = new IrritantDb();


    //Version 1 - The Model's property is coded in IrritantViewModel
    //private short _id;
    //private string _name = "Alen";
    //private string _description;

    //public short Id
    //{
    //    get { return _id; }
    //    set { SetProperty(ref _id, value); }
    //}

    //public string Name
    //{
    //    get { return _name; }
    //    set { SetProperty(ref _name, value); }
    //}

    //public string Description
    //{
    //    get { return _description; }
    //    set { SetProperty(ref _description, value); }
    //}


    //Version2 - I use the Irritant Model as property of IrritantViewModel
    private DateTime? _lastUpdated;
    private Irritant _entity;

    public Irritant Entity
    {
        get { return _entity; }
        set { SetProperty(ref _entity, value); }
    }

    public DateTime? LastUpdated
    {
        get { return _lastUpdated; }
        set { SetProperty(ref _lastUpdated, value); }
    }

    public DelegateCommand UpdateCommand { get; set; }

    public IrritantViewModel()
    {
        Entity = new Irritant();

        //Version1
        //UpdateCommand = new DelegateCommand(EditCommand, CanExecute).ObservesProperty(() => Name);

        //Version2
        UpdateCommand = new DelegateCommand(EditCommand, CanExecute).ObservesProperty(() => Entity.Name);
    }

    private bool CanExecute()
    {
        //Version1
        //switch (Name)
        //{
        //    case null:
        //        return false;
        //    case "":
        //        return false;
        //}


        //Version2
        switch (Entity.Name)
        {
            case null:
                return false;
            case "":
                return false;
        }

        return true;
    }

    private void EditCommand()
    {
        LastUpdated = DateTime.UtcNow;
    }
}

这是我的观点

public partial class IrritantView : UserControl
{
    public IrritantView()
    {
        InitializeComponent();
        DataContext = new IrritantViewModel();
    }
}

<Grid >
    <ScrollViewer>
        <StackPanel MinWidth="200">

        <TextBlock Text="Irritant"  />



        <!--Version 1-->
                <!--<TextBlock Text="Name" />
                <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
                <TextBlock Text="Description" />
                <TextBox Text="{Binding Description, UpdateSourceTrigger=PropertyChanged}" />
                -->


        <!--Version 2-->

            <TextBlock Text="Name" />
            <TextBox Text="{Binding Entity.Name, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text="Description" />
            <TextBox Text="{Binding Entity.Description, UpdateSourceTrigger=PropertyChanged}" />



            <TextBlock Text="Last Updated" />
            <Label Content="{Binding LastUpdated, UpdateSourceTrigger=PropertyChanged}" />
            <Button Content="Save" 
                    Command="{Binding UpdateCommand}"
                    />
        </StackPanel>
    </ScrollViewer>
</Grid>

Version1 工作正常,当绑定到 Name (TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}") 的 TextBox 为 null 或为空时,Save 按钮会禁用.

The Version1 works fine, the Save Button disables when the TextBox that is bound to Name (TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}") is null or empty.

但在版本 2 中,保存按钮不会禁用.它仅在初始化期间调用 CanExecute 方法,移除 TextBox 中的文本不会禁用 Button.我做错了什么?

But with version 2, the Save Button doesn't disable. It only calls the method CanExecute during initialization, removing the text in the TextBox doesn't disable the Button. What did I do wrong?

推荐答案

DelegateCommand 不会自动引发 CanExecuteChanged 事件,您必须通过调用 CanExecuteChanged 手动引发该事件code>RaiseCanExecuteChanged 在适当的时候.除了使用 DelegateCommand,您还可以使用 RelayCommand 中继CommandManager.RequerySuggested 事件,为您做类似的事情.

DelegateCommand doesn't raise CanExecuteChanged event automatically, you have to raise that event manually by calling RaiseCanExecuteChanged when appropriate. Apart from using DelegateCommand, you can use RelayCommand which relays on CommandManager.RequerySuggested event which do the similar thing for you.

  1. 更改您的命令定义返回 ICommand:

public ICommand UpdateCommand { get; set; }

  • 使用以下命令初始化命令:

  • Initialize the command using below:

    UpdateCommand = new AutoCanExecuteCommand(new DelegateCommand(EditCommand, CanExecute));
    

  • 使用以下类作为包装器:

  • Use the following class as a wrapper:

    public class AutoCanExecuteCommand : ICommand
    {
        public ICommand WrappedCommand { get; private set; }
    
        public AutoCanExecuteCommand(ICommand wrappedCommand)
        {
            if (wrappedCommand == null) 
            {
                throw new ArgumentNullException("wrappedCommand");
            }
    
            WrappedCommand = wrappedCommand;
        }
    
        public void Execute(object parameter)
        {
            WrappedCommand.Execute(parameter);
        }
    
        public bool CanExecute(object parameter)
        {
            return WrappedCommand.CanExecute(parameter);
        }
    
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
    

  • 这篇关于如何使用 Prism 6 正确触发 CanExecute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆