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 コレクションには少なくとも 1 つの値が含まれています

次のことを試しましたが、コマンドに接続されているボタンが有効にならないため、機能しません。

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);

アイテムがコレクションに追加またはコレクションから削除されるとすぐに、コマンドに接続されているボタンが正しく有効または無効になるため、これは実行基準の 2 番目の部分で機能します。

私の質問は、ShareText プロパティが null または空でないことを確認することとどのように組み合わせることができるかということです。

accountsSelected 変数はプロパティではないため、 this.WhenAny(..) メソッドはもう使用できません。

ありがとう

4

2 に答える 2

7

で WhenAny を使用するの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));

ここでの利点は、 SelectedAccountsを再割り当てWhenAnyObservableすることを決定した場合(つまり、上記のステートメントは引き続き機能しますが、上記のステートメントはまだ古いコレクションをリッスンしていることです。SelectedAccounts = new ReactiveCollection(...);

于 2013-03-19T01:42:05.990 に答える
1

期待される結果を得るにはさまざまな方法があると思いますが、これは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 に答える