ReactiveCommand与CanExecute的组合标准



我刚刚开始使用ReactiveUI。我有以下类:

public class MainViewModel : ReactiveObject, IRoutableViewModel 
{
   private string shareText;
   public ReactiveCollection<SharingAccountViewModel> SelectedAccounts { get; private set; }
   public string ShareText 
   { 
      get { return shareText; }
      set
      {
          this.RaiseAndSetIfChanged(ref shareText, value);
      }
   }
   public IReactiveCommand ShareCommand { get; private set; }
}

我想做的是允许命令在满足以下条件时执行:

  1. ShareText属性不为空或空
  2. SelectedAccounts集合至少包含一个值

我已经尝试了以下操作,但它不起作用,因为连接到命令的按钮从未启用:

ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
  viewModel => viewModel.SelectedAccounts,
  (x, y) => !String.IsNullOrEmpty(x.Value) && y.Value.Count > 0));

如果我只是检查ShareText属性,然而,它工作得很好:

  ShareCommand = new ReactiveCommand(this.WhenAny(viewModel => viewModel.ShareText,
            (x) => !String.IsNullOrEmpty(x.Value)));

我看了一下问题ReactiveUI的答案:使用CanExecute与一个ReactiveCommand

基于此,我尝试了以下操作:

var accountsSelected = SelectedAccounts.CollectionCountChanged.Select(count => count > 0);
ShareCommand = new ReactiveCommand(accountsSelected);

这对于我的执行条件的第二部分是有效的,因为只要从集合中添加或删除项,连接到命令的按钮就会正确地启用或禁用。

我的问题是我现在如何与检查ShareText属性不为空或空相结合?

我不能再使用this.WhenAny(..)方法了,因为accountsSelected变量不是一个属性。

谢谢

IObservable一起使用WhenAny有点棘手。我是这样做的:

var canShare = Observable.CombineLatest(
    this.WhenAnyObservable(x => x.SelectedAccounts.CollectionCountChanged),
    this.WhenAny(x => x.ShareText, x => x.Value),
    (count, text) => count > 0 && !String.IsNullOrWhitespace(text));

这里WhenAnyObservable的优点是,如果您决定重新分配 SelectedAccounts(即SelectedAccounts = new ReactiveCollection(...);),上面的语句仍然可以工作,而上面的语句仍然会监听旧集合。

我相信有不同的方法来获得预期的结果,这只是一种方法。

var canExecute = this.ObservableForProperty(v => v.ShareText)
                         .Select(_ => Unit.Default)
                  .Merge(SelectedAccounts.CollectionCountChanged
                                     .Select(_ => Unit.Default))
                  .Select(_ => !String.IsNullOrEmpty(ShareText)
                                    && SelectedAccounts.Any())
                  .StartWith(false);
ShareCommand = new ReactiveCommand(canExecute);

相关内容

  • 没有找到相关文章

最新更新