Karmaşık senaryolarda komutun kullanılabilirliğini denetlemek için RX nasıl kullanılır?

0

Soru

Kurulum

Aşağıdakileri varsayalım. WPF uygulaması için aşağıdaki teorik viewmodel sınıfımız var:

public MyViewModel
{

    public MyViewModel()
    {
        // Condition under which this command may be executed is:
        // this.ActiveDocument.Highlighting.Type == Highlighting.Xml && 
        //    !this.ActiveDocument.IsReadOnly && 
        //    (this.License.Kind == LicenseKind.Full || this.License.TrialDay < 30)
        MyCommand = new Command(obj => DoSomething());
    }

    public ICommand MyCommand { get; } 
    // (all other required properties)
}

Ek olarak:

  • Geçerli sınıf düzgün bir şekilde uygular INotifyPropertyChanged
  • Üye erişim zincirlerindeki tüm sınıflar düzgün şekilde uygulanır INotifyPropertyChanged (örn. belge viewmodel erişilebilir ActiveDocument özellik)
  • ActiveDocument olabilir null. ActiveDocument.Highlighting ayrıca null olabilir.

Sorun

Komutun yalnızca yorumdaki koşul karşılandığında etkinleştirilmesini istiyorum.

RX olmadan seçeneği

Ben yazdım benim kendi Kütüphanesi için kullanma gibi durumlar. Çözüm ya olurdu:

public MyViewModel
{
    private readonly Condition commandAvailableCondition;

    public MyViewModel()
    {
        commandAvailableCondition = new LambdaCondition(this, 
            vm => m.ActiveDocument.Highlighting.Type == Highlighting.Xml && 
                !vm.ActiveDocument.IsReadOnly && 
                (vm.License.Kind == LicenseKind.Full || vm.License.TrialDay < 30),
            false);

        MyCommand = new AppCommand(obj => DoSomething(), commandAvailableCondition);
    }

    public ICommand MyCommand { get; } 
    // (all other required properties)
}

Veya-kodun biraz daha okunabilir olmasını istiyorsanız, böylece kısmi koşullar yeniden kullanılabilir-bunun gibi:

public MyViewModel
{
    private readonly Condition commandAvailableCondition;

    public MyViewModel()
    {
        var highlightingIsXml = new LambdaCondition(this, 
            vm => vm.ActiveDocument.Highlighting.Type == Highlighting.Xml, 
            false);
        var documentIsReadonly = new LambdaCondition(this,
            vm => vm.ActiveDocument.IsReadOnly, 
            false);
        var appIsLicensed = new LambdaCondition(this,
            vm => vm.License.Kind == LicenseKind.Full || this.License.TrialDay < 30,
            false);

        commandAvailableCondition = highlightingIsXml & !documentIsReadonly & appIsLicensed;

        MyCommand = new AppCommand(obj => DoSomething(), commandAvailableCondition);
    }

    public ICommand MyCommand { get; } 
    // (all other required properties)
}

Kütüphanem nedir (veya daha doğrusu, LambdaCondition sınıf) yapar:

  • Uygulayan tüm örnekleri takip eder INotifyPropertyChanged ve değişiklikleri ele alın (örn. ne zaman ActiveDocument değişiklikler veya ActiveDocument.Highlighting değişiklikler veya ActiveDocument.Highlighting.Type vb değişiklikler.)
  • Bu mümkün izler nulls yolda, bu durumda varsayılan değeri döndürür (bu durumda, false)
  • Otomatik olarak UI gerektiğinde yenilenmesi komutu için kullanılabilirlik çocuk (değişiklik), değişiklik raporları olacaktır.

Soru

Yukarıda açıklanan senaryoyu kullanarak nasıl uygulayabilirim System.Reactive C # ' da mı? Tüm gereklilikleri yerine getirirken bunu kolayca yapmak mümkün mü INotifyPropertyChanged, yoldaki boş değerler ve varsayılan değer? Gerektiğinde mantıklı varsayımlarda bulunabilirsiniz.

c# mvvm system.reactive wpf
2021-11-23 15:15:48
1

En iyi cevabı

0

ReactiveUI çerçevesi bir ReactiveCommand bir sınıf kullanan IObservable<T> komutun durumunu yenilemek için (örn. CanExecuteChanged etkinliğin ICommand).

Yürütülebilirliği kontrol etmek için nasıl kullanılacağına dair bir örnek için lütfen dokümanlar'a bakın:

var canExecute = this.WhenAnyValue(
    x => x.UserName, x => x.Password,
    (userName, password) => 
        !string.IsNullOrEmpty(userName) && 
        !string.IsNullOrEmpty(password));

var command = ReactiveCommand.CreateFromTask(LogOnAsync, canExecute);
2021-11-24 14:52:33

Özellik erişim zincirindeki INotifyPropertyChange uygulayıcılarını takip ediyor mu? Özelliklerden herhangi biri null ise de düzgün çalışıyor mu? Rx'te uygulandığında özel örneğimin nasıl görüneceğini gösterebilir misiniz?
Spook

WhenAnyValue aşağıdakilerden herhangi biri olduğunda yeni bir değer yayar mı Username ve Password özellikleri rasises PropertyChanged etkinlik. Özel örneğiniz tam olarak nedir? Ne denedin?
mm8

Yaptığın okumak benim bütün soru? İzlenmesi gereken kesin durumu sundum.: vm => m.ActiveDocument.Highlighting.Type == Highlighting.Xml && !vm.ActiveDocument.IsReadOnly && (vm.License.Kind == LicenseKind.Full || vm.License.TrialDay < 30), Eğer örneğin eğer. ActiveDocument null mu? RX düzgün halledecek mi? Bu durumda koşulun varsayılan değerine (veya en azından varsayılan olarak false) sahip olmasını bekliyorum.
Spook

Eğer ActiveDocument olur mu get NullReferenceException. Bunun RX ile ilgisi yok.
mm8

Bu, diğerlerinin yanı sıra, bu yüzden rx'in bu görev için uygun olup olmadığını merak ediyorum.
Spook

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................