我有个模特
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有两个版本
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工作正常,当绑定到名称的TextBox (TextBox Text="{Binding,UpdateSourceTrigger=PropertyChanged}")为空或空时,保存按钮将禁用。
但是对于版本2,Save并没有禁用。它只在初始化时调用CanExecute方法,删除TextBox中的文本不会禁用Button。我做错什么了?
发布于 2015-11-02 14:05:49
DelegateCommand
不会自动引发CanExecuteChanged
事件,您必须在适当时通过调用RaiseCanExecuteChanged
来手动引发该事件。除了使用DelegateCommand
之外,您还可以使用RelayCommand
,它可以在为您做类似事情的CommandManager.RequerySuggested
事件上进行中继。
ICommand
:
公共ICommand UpdateCommand { get;set;}发布于 2015-11-02 18:51:27
出于几个原因,我不建议与CommandManager挂钩。除了内存泄漏之外,它还会在应用程序中引入性能问题,因为您无法控制CommandManager何时或多少次调用CanExecute (这发生在UI线程上)。相反,我建议使用模型对象的INPC,如下所示:
ObservesProperty method isn't observing model's properties at Prism 6
https://stackoverflow.com/questions/33459183
复制相似问题