ReactiveUI:将CanExecute与ReactiveCommand一起使用

时间:2011-07-19 22:34:33

标签: silverlight mvvm system.reactive reactiveui

我开始在Silverlight项目上使用ReactiveUI框架,需要一些使用ReactiveCommands的帮助。

在我的视图模型中,我看起来大致相似(这只是一个简化的例子):

public class MyViewModel : ReactiveObject
{
  private int MaxRecords = 5;

  public ReactiveCommand AddNewRecord { get; protected set; }

  private ObservableCollection<string> _myCollection = new ObservableCollection<string>();
  public ObservableCollection<string> MyCollection
  {
    get
    {
      return _myCollection;
    }

    set
    {
      _myCollection = value;
      raiseCollectionChanged("MyCollection");
    }
  }

  MyViewModel()
  {
    var canAddRecords = Observable.Return<bool>(MyCollection.Count < MaxRecords);
    AddNewRecord = new ReactiveCommand(canAddRecords);

    AddNewRecord.Subscribe(x => 
    {
       MyCollection.Add("foo");
    }
  }
}

canAddRecords函数在第一次创建ReactiveCommand时进行评估,但在将项目添加到MyCollection时不会重新评估。任何人都可以向我展示如何绑定canExecute的{​​{1}}属性的一个很好的示例,以便在这种情况下自动重新评估它吗?

2 个答案:

答案 0 :(得分:5)

实际上,有一种更好的方法,将ObservableCollection更改为ReactiveCollection(继承自ObservableCollection但添加了一些额外的属性):

MyCollection = new ReactiveCollection<string>();

AddNewRecord = new ReactiveCommand(
    MyCollection.CollectionCountChanged.Select(count => count < MaxRecords));

现在这里的问题是,你不能覆盖 MyCollection,只能重新填充它(即Clear()+ Add())。让我知道,如果这是一个交易破坏者,虽然这是一个更多的工作,但有一种方法来解决这个问题。

答案 1 :(得分:3)

我终于想到了这一个。使用ReactiveCommand.Create()适用于我的情况。

MyViewModel()
{
  AddNewRecord = ReactiveCommand.Create(x => MyCollection.Count < MaxRecords);

  AddNewRecord.Subscribe(x => 
  {
     MyCollection.Add("foo");
  }
}