首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Prism 6正确制作CanExecute触发器

如何使用Prism 6正确制作CanExecute触发器
EN

Stack Overflow用户
提问于 2015-11-01 04:20:35
回答 2查看 2.8K关注 0票数 1

我有个模特

代码语言:javascript
运行
复制
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有两个版本

代码语言:javascript
运行
复制
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;
    }
}

这就是我的观点

代码语言:javascript
运行
复制
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工作正常,当绑定到名称的TextBox (TextBox Text="{Binding,UpdateSourceTrigger=PropertyChanged}")为空或空时,保存按钮将禁用。

但是对于版本2,Save并没有禁用。它只在初始化时调用CanExecute方法,删除TextBox中的文本不会禁用Button。我做错什么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-02 14:05:49

DelegateCommand不会自动引发CanExecuteChanged事件,您必须在适当时通过调用RaiseCanExecuteChanged来手动引发该事件。除了使用DelegateCommand之外,您还可以使用RelayCommand,它可以在为您做类似事情的CommandManager.RequerySuggested事件上进行中继。

  1. 更改命令定义,返回ICommand: 公共ICommand UpdateCommand { get;set;}
  2. 使用以下方法初始化命令: UpdateCommand =新AutoCanExecuteCommand(新DelegateCommand(EditCommand,CanExecute));
  3. 使用以下类作为包装: 公共类AutoCanExecuteCommand : ICommand { public ICommand WrappedCommand { get;私有集;} public AutoCanExecuteCommand(ICommand wrappedCommand) { if (wrappedCommand == null) {抛出新ArgumentNullException(" WrappedCommand ");}wrappedCommand= wrappedCommand;} public void (对象参数){WrappedCommand.Execute(参数);}公共bool CanExecute(对象参数){返回WrappedCommand.CanExecute(参数);}公共事件EventHandler CanExecuteChanged {添加{ CommandManager.RequerySuggested +=值;}删除{ CommandManager.RequerySuggested -=值;}
票数 4
EN

Stack Overflow用户

发布于 2015-11-02 18:51:27

出于几个原因,我不建议与CommandManager挂钩。除了内存泄漏之外,它还会在应用程序中引入性能问题,因为您无法控制CommandManager何时或多少次调用CanExecute (这发生在UI线程上)。相反,我建议使用模型对象的INPC,如下所示:

ObservesProperty method isn't observing model's properties at Prism 6

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33459183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档