Il programma di installazione
Si ipotizzi il seguente. Abbiamo il seguente teorico classe viewmodel per applicazione 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)
}
Inoltre:
- Classe implementa correttamente
INotifyPropertyChanged
- Tutte le classi di accesso ai membri delle catene implementa correttamente
INotifyPropertyChanged
(es. documento viewmodel accessibile daActiveDocument
la struttura) ActiveDocument
può esserenull
.ActiveDocument.Highlighting
può anche essere null.
Il problema
Vorrei il comando per essere attivata solo quando la condizione in commento è soddisfatta.
Opzione senza RX
Ho scritto la mia libreria per la gestione di tali situazioni. La soluzione potrebbe essere:
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)
}
O - se si desidera che il codice di essere un po ' più leggibile, in modo parziale le condizioni potrebbero essere riutilizzati come che:
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)
}
Quello che la mia libreria (o, più precisamente, LambdaCondition
classe) è:
- Esso tiene traccia di tutte le istanze di attuazione
INotifyPropertyChanged
e gestire i cambiamenti (es. quandoActiveDocument
modifiche oActiveDocument.Highlighting
modifiche oActiveDocument.Highlighting.Type
modifiche etc.) - Esso tiene traccia di possibili
null
s sul modo in cui il caso verrà restituito il valore di default (in questo caso,false
) - Automaticamente i rapporti di modifiche (ma cambia solo) di disponibilità a comando, in modo che l'interfaccia utente può essere aggiornata quando necessario.
La domanda
Come implementare lo scenario sopra descritto utilizzando System.Reactive
in C#? È possibile farlo facilmente, mantenendo tutte le esigenze INotifyPropertyChanged
i valori null e sul modo in cui il valore di default? Si può fare qualsiasi sano di mente ipotesi, quando necessario.