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şilebilirActiveDocument
özellik) ActiveDocument
olabilirnull
.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 zamanActiveDocument
değişiklikler veyaActiveDocument.Highlighting
değişiklikler veyaActiveDocument.Highlighting.Type
vb değişiklikler.) - Bu mümkün izler
null
s 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.