当文档更改时在 postsharp [Command] 上触发 "CanExecute"?
Triggering "CanExecute" on postsharp [Command] when a document changes?
我目前正在将一个项目迁移到 PostSharp 以删除大量样板代码,大部分都进行得非常顺利,但我对如何强制命令重新检查感到困惑CanExecute
。我希望 PostSharp 会像检查属性一样检查命令以检查依赖项,这是一个极简主义示例
[NotifyPropertyChanged]
public class MyWindowViewModel
{
/// Anything bound to this refreshes just fine as expected
public ObservableCollection<SomeType> Documents = new ObservableCollection<SomeType>();
[Command]
public ICommand AddDocumentCommand { get; set; }
public void ExecuteAddDocument () { Documents.Add(new SomeType()); }
[Command]
public ICommand CloseDocumentCommand { get; set; }
public bool CanExecuteCloseDocument () => Documents.Any();
public void ExecuteCloseDocument () { Documents.Remove(Documents.Last()); }
}
开始时集合是空的,关闭命令的按钮按预期显示为灰色,但是通过 AddDocument
的按钮添加文档不会激活关闭文档按钮,这是什么适当的方式来完成我需要的? PostSharp 是否只将赋值而不是方法调用视为更改,还是完全不同?
根据他们的 Command 文档
CanExecuteCloseDocument
应该是 属性
public bool CanExecuteCloseDocument => Documents.Any();
当命令需要参数时使用method选项,
The command availability check that depends on the input argument can be implemented as a method.
例如
public bool CanExecuteCloseDocument (int blah) => Documents.Any();
public void ExecuteCloseDocument (int blah) { Documents.Remove(Documents.Last()); }
除此之外,这里的主要问题是视图不知道集合的更改知道刷新 属性 更改。
参考这个http://www.postsharp.net/blog/post/Announcing-PostSharp-42-RC
Dependencies to collections
When you add the [AggregateAllChanges]
attribute to a field or
automatic property, any change to a property of the object assigned to
this field/property will be interpreted as a change to the
field/property itself. The attribute now works only for collections.
[NotifyPropertyChanged]
public class MyWindowViewModel {
/// Anything bound to this refreshes just fine as expected
[AggregateAllChanges] // <-- when the collection changes to cause notification
public ObservableCollection<SomeType> Documents { get; } = new ObservableCollection<SomeType>();
[Command]
public ICommand AddDocumentCommand { get; set; }
public void ExecuteAddDocument () { Documents.Add(new SomeType()); }
[Command]
public ICommand CloseDocumentCommand { get; set; }
public bool CanExecuteCloseDocument => Documents.Any();
public void ExecuteCloseDocument () { Documents.Remove(Documents.Last()); }
}
使用 PostSharp LINQ 表达式 (or virtual calls, delegates, external methods) 不适用于 CanExecute。
但是实现 INotifyPropertyChanged 的属性的表达式非常棒(即使对于嵌套属性)。 ObservableCollection 实现了 INotifyPropertyChanged,我们不需要 LINQ:
public bool CanExecuteCloseDocument => Documents.Count > 0;
我目前正在将一个项目迁移到 PostSharp 以删除大量样板代码,大部分都进行得非常顺利,但我对如何强制命令重新检查感到困惑CanExecute
。我希望 PostSharp 会像检查属性一样检查命令以检查依赖项,这是一个极简主义示例
[NotifyPropertyChanged]
public class MyWindowViewModel
{
/// Anything bound to this refreshes just fine as expected
public ObservableCollection<SomeType> Documents = new ObservableCollection<SomeType>();
[Command]
public ICommand AddDocumentCommand { get; set; }
public void ExecuteAddDocument () { Documents.Add(new SomeType()); }
[Command]
public ICommand CloseDocumentCommand { get; set; }
public bool CanExecuteCloseDocument () => Documents.Any();
public void ExecuteCloseDocument () { Documents.Remove(Documents.Last()); }
}
开始时集合是空的,关闭命令的按钮按预期显示为灰色,但是通过 AddDocument
的按钮添加文档不会激活关闭文档按钮,这是什么适当的方式来完成我需要的? PostSharp 是否只将赋值而不是方法调用视为更改,还是完全不同?
根据他们的 Command 文档
CanExecuteCloseDocument
应该是 属性
public bool CanExecuteCloseDocument => Documents.Any();
当命令需要参数时使用method选项,
The command availability check that depends on the input argument can be implemented as a method.
例如
public bool CanExecuteCloseDocument (int blah) => Documents.Any();
public void ExecuteCloseDocument (int blah) { Documents.Remove(Documents.Last()); }
除此之外,这里的主要问题是视图不知道集合的更改知道刷新 属性 更改。
参考这个http://www.postsharp.net/blog/post/Announcing-PostSharp-42-RC
Dependencies to collections
When you add the
[AggregateAllChanges]
attribute to a field or automatic property, any change to a property of the object assigned to this field/property will be interpreted as a change to the field/property itself. The attribute now works only for collections.
[NotifyPropertyChanged]
public class MyWindowViewModel {
/// Anything bound to this refreshes just fine as expected
[AggregateAllChanges] // <-- when the collection changes to cause notification
public ObservableCollection<SomeType> Documents { get; } = new ObservableCollection<SomeType>();
[Command]
public ICommand AddDocumentCommand { get; set; }
public void ExecuteAddDocument () { Documents.Add(new SomeType()); }
[Command]
public ICommand CloseDocumentCommand { get; set; }
public bool CanExecuteCloseDocument => Documents.Any();
public void ExecuteCloseDocument () { Documents.Remove(Documents.Last()); }
}
使用 PostSharp LINQ 表达式 (or virtual calls, delegates, external methods) 不适用于 CanExecute。
但是实现 INotifyPropertyChanged 的属性的表达式非常棒(即使对于嵌套属性)。 ObservableCollection 实现了 INotifyPropertyChanged,我们不需要 LINQ:
public bool CanExecuteCloseDocument => Documents.Count > 0;