wpf - Prism :必须显式调用 RaiseCanExecuteChanged()

标签 wpf mvvm prism delegatecommand

下面是一个很简单的Prism.WpfDelegateCommand 为例两者都有ExecuteCanExecute代表。

假设 CanExecute取决于某些属性。看来 Prism 的DelegateCommand不重新评估 CanExecute当此属性更改时自动条件,如 RelayCommand在其他 MVVM 框架中确实如此。相反,您必须在属性 setter 中显式调用 RaiseCanExecuteChanged()。这会导致在任何重要的 View 模型中出现大量重复代码。

有没有更好的办法?

View 模型:

using System;
using Prism.Commands;
using Prism.Mvvm;

namespace PrismCanExecute.ViewModels
{
public class MainWindowViewModel : BindableBase
{
    private string _title = "Prism Unity Application";
    public string Title
    {
        get { return _title; }
        set { SetProperty(ref _title, value); }
    }
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            SetProperty(ref _name, value);

            // Prism doesn't track CanExecute condition changes?
            // Have to call it explicitly to re-evaluate CanSubmit()
            // Is there a better way?
            SubmitCommand.RaiseCanExecuteChanged();
        }
    }
    public MainWindowViewModel()
    {
        SubmitCommand = new DelegateCommand(Submit, CanSubmit);
    }

    public DelegateCommand SubmitCommand { get; private set; }
    private bool CanSubmit()
    {
        return (!String.IsNullOrEmpty(Name));
    }
    private void Submit()
    {
        System.Windows.MessageBox.Show(Name);
    }

}
}

看法:
<Window x:Class="PrismCanExecute.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="525"
    Height="350"
    prism:ViewModelLocator.AutoWireViewModel="True">
<Grid>
    <!--<ContentControl prism:RegionManager.RegionName="ContentRegion" />-->
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Name: " />
            <TextBox Width="150"
                     Margin="5"
                     Text="{Binding Name,  UpdateSourceTrigger=PropertyChanged}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Width="50"
                    Command="{Binding SubmitCommand}"
                    Content="Submit" Margin="10"/>
            <!--<Button Width="50"
                    Content="Cancel"
                    IsCancel="True" Margin="10"/>-->
        </StackPanel>
    </StackPanel>
</Grid>
</Window>

最佳答案

正如@l33t 解释的那样,这是设计的。如果您希望 DelegateCommand 自动监视 VM 属性的更改,只需使用 delegateCommand 的 ObservesProperty 方法:

var command = new DelegateCommand(Execute).ObservesProperty(()=> Name);

关于wpf - Prism :必须显式调用 RaiseCanExecuteChanged(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38958379/

相关文章:

wpf - Prism Mvvm Mef Interactivity 打开窗口新实例

AvalonDock 的 DocumentPane 和 DockingPane 的 Prism2 区域适配器?

wpf - WPF ViewModel第一种方法-同一 View 中同一用户控件的多个实例

wpf - 在控制上调用 "function"

wpf - 以MVVM模式将数据传递给用户控制

c# - WPF 绑定(bind)不接受任何更改

c# - 我应该如何过滤绑定(bind)到网格的 IReactiveList?

c# - 使用 .resx 文件本地化 Prism 4 模块

c# - 如何分配 ItemsSource 属性

wpf - WPF UserControl上的依赖注入(inject)(Windsor)