Configurarea
Să presupunem următoarele. Avem un text teoretic viewmodel clasa de aplicație WPF:
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)
}
În plus:
- Actuala clasă implementează în mod corespunzător
INotifyPropertyChanged
- Toate clasele din statele acces lanțuri pune în aplicare în mod corespunzător
INotifyPropertyChanged
(de exemplu. document accesibil din viewmodelActiveDocument
de proprietate) ActiveDocument
poate finull
.ActiveDocument.Highlighting
poate fi, de asemenea, nul.
Problema
Mi-ar place comandă să fie activată numai atunci când starea în comentariu este cunoscut.
Opțiune fără RX
Am scris propria mea bibliotecă pentru a gestiona aceste situații. Soluția ar fi:
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)
}
Sau - dacă doriți codul fi un pic mai ușor de citit, așa că parțială condiții ar putea fi refolosite - așa:
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)
}
Ce biblioteca mea (sau, mai precis, LambdaCondition
clasa) nu este:
- Ea ține evidența tuturor cazuri de punere în aplicare
INotifyPropertyChanged
și mâner modificări (de exemplu. cândActiveDocument
modificări sauActiveDocument.Highlighting
modificări sauActiveDocument.Highlighting.Type
modificări etc.) - Ea ține evidența posibil
null
e pe drum, caz în care se va returna valoarea implicită (în acest caz,false
) - Acesta va automat rapoarte de modificări (dar numai modificări) disponibilitatea de a comanda, astfel încât UI pot fi actualizate atunci când este necesar.
Întrebarea
Cum s-ar pune în aplicare scenariul descris mai sus, folosind System.Reactive
in C#? Este posibil să se facă cu ușurință păstrând în același timp toate cerințele despre INotifyPropertyChanged
, null-uri pe drum și valoarea implicită? S-ar putea face orice sănătoasă ipoteze atunci când este necesar.