1

我刚刚开始使用 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 属性不为 null 或为空
  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: Using CanExecute with a ReactiveCommand的答案

基于此,我尝试了以下方法:

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

这适用于我的执行标准的第二部分,因为一旦从集合中添加或删除项目,连接到命令的按钮就会正确启用或禁用。

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

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

谢谢

4

2 回答 2

7

将 WhenAny 与 an 一起使用IObservable有点棘手。这是我的做法:

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(...);,上面的语句仍然有效,而上面的语句仍然会监听旧集合。

于 2013-03-19T01:42:05.990 回答
1

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

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);
于 2013-03-18T21:27:46.700 回答