Prism:必须显式调用 RaiseCanExecuteChanged() [英] Prism: have to call RaiseCanExecuteChanged() explicitly
问题描述
下面是一个非常简单的 Prism.Wpf
示例,其中 DelegateCommand
具有 Execute
和 CanExecute
委托.
Below is a very simple Prism.Wpf
example with a DelegateCommand
that has both Execute
and CanExecute
delegates.
假设 CanExecute
依赖于某个属性.似乎 Prism 的 DelegateCommand
不会在此属性更改时自动重新评估 CanExecute
条件,就像 RelayCommand
在其他 MVVM 框架中所做的那样.相反,您必须在属性设置器中显式调用 RaiseCanExecuteChanged().这会导致在任何非平凡的视图模型中出现大量重复代码.
Suppose that CanExecute
depends on some property. It seems that Prism's DelegateCommand
doesn't re-evaluate CanExecute
condition automatically when this property changes, as RelayCommand
does in other MVVM frameworks. Instead, you have to call RaiseCanExecuteChanged() explicitly in the property setter. This leads to a lot of repetitive code in any non-trivial viewmodel.
有没有更好的方法?
视图模型:
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 方法:
As @l33t explained, this is by deign. If you want the DelegateCommand to monitor VM properties for changes automatically, just use the ObservesProperty method off of the delegateCommand:
var command = new DelegateCommand(Execute).ObservesProperty(()=> Name);
这篇关于Prism:必须显式调用 RaiseCanExecuteChanged()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!