Nastavení
Předpokládejme, že následující. Máme následující teoretické viewmodel třídy pro WPF aplikace:
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)
}
Kromě toho:
- Aktuální třída implementuje správně
INotifyPropertyChanged
- Všechny třídy v členských přístup řetězy implementuje správně
INotifyPropertyChanged
(např. dokument viewmodel přístupné zActiveDocument
majetku) ActiveDocument
může býtnull
.ActiveDocument.Highlighting
může být také null.
Problém
Rád bych příkaz, který má být povolena pouze tehdy, když stav, v komentáři je splněna.
Možnost bez RX
Napsal jsem můj vlastní knihovny pro zpracování takových situací. Řešením by mohlo být buď:
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)
}
Nebo - pokud chcete kód být trochu čitelnější, a to tak, že dílčí podmínky by mohly být znovu použity - jako, že:
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)
}
Co je moje knihovna (nebo, přesněji řečeno, LambdaCondition
třídy) je:
- To udržuje všechny instance provádění
INotifyPropertyChanged
a zpracovávat změny (např. kdyžActiveDocument
změny neboActiveDocument.Highlighting
změny neboActiveDocument.Highlighting.Type
změny atd.) - To udržuje, je to možné
null
s cestou v takovém případě vrátí výchozí hodnotu (v tomto případě,false
) - To bude automaticky hlásí změny (ale pouze změny) dostupnost příkazu, tak, že uživatelské ROZHRANÍ může být aktualizován v případě potřeby.
Otázka
Jak by se dalo realizovat scénář je popsáno výše, pomocí System.Reactive
v C#? Je možné to udělat snadno při zachování všech požadavků o INotifyPropertyChanged
, hodnoty null a výchozí hodnota? Můžete si vytvořit nějaký rozumný předpoklady v případě potřeby.