当文档发生变化时,在postsharp [Command]上触发"CanExecute"?

Ron*_*dau 7 .net c# wpf postsharp

我目前正在将一个项目迁移到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()); }        
}
Run Code Online (Sandbox Code Playgroud)

在开始时,集合是空的,并且关闭命令的按钮按预期变灰,但是通过附加的按钮添加文档AddDocument不会激活关闭文档按钮,什么是完成我需要的适当方法?PostSharp是仅将赋值而非方法调用视为更改还是完全不同于其他内容?

Nko*_*osi 7

根据他们的Command文档

CanExecuteCloseDocument 应该是一个财产

public bool CanExecuteCloseDocument => Documents.Any();
Run Code Online (Sandbox Code Playgroud)

当命令需要参数时使用方法选项,

取决于输入参数的命令可用性检查可以作为方法实现.

例如

public bool CanExecuteCloseDocument (int blah) => Documents.Any(); 
public void ExecuteCloseDocument (int blah) { Documents.Remove(Documents.Last()); }
Run Code Online (Sandbox Code Playgroud)

除此之外,主要问题是视图不知道要知道刷新属性更改的集合的更改.

请参阅此http://www.postsharp.net/blog/post/Announcing-PostSharp-42-RC

对集合的依赖性

[AggregateAllChanges]属性添加到字段或自动属性时,对分配给此字段/属性的对象的属性的任何更改都将被解释为对字段/属性本身的更改.该属性现在仅适用于集合.

[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()); }        
}
Run Code Online (Sandbox Code Playgroud)