Le programme d'installation
Supposons ce qui suit. Nous avons un théorique classe viewmodel pour application 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)
}
En outre:
- Actuelle classe implémente correctement
INotifyPropertyChanged
- Toutes les classes dans l'accès des membres des chaînes implémente correctement
INotifyPropertyChanged
(eg. document viewmodel accessible à partir deActiveDocument
de la propriété) ActiveDocument
peut-êtrenull
.ActiveDocument.Highlighting
peut également être null.
Le problème
J'aimerais que la commande doit être activée uniquement lorsque la condition de commentaire est rencontré.
Option sans RX
J'ai écrit ma propre bibliothèque pour la manipulation de telles situations. La solution serait soit:
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)
}
Ou - si vous voulez que le code soit un peu plus lisible, de sorte que partielle, les conditions pourraient être réutilisés, comme ç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 que ma bibliothèque (ou, plus précisément, LambdaCondition
de classe) est la suivante:
- Il garde la trace de toutes les instances de mise en œuvre
INotifyPropertyChanged
et de gérer les changements (par exemple. lorsqueActiveDocument
des modifications ou desActiveDocument.Highlighting
des modifications ou desActiveDocument.Highlighting.Type
etc.) - Il garde la trace de possible
null
s sur la façon dont les cas, il sera de retour la valeur par défaut (dans ce cas,false
) - Il sera automatiquement des rapports de changements (changements seulement) de la disponibilité à la commande, de sorte que l'INTERFACE utilisateur peut être actualisée en cas de besoin.
La question
Comment mettre en œuvre le scénario décrit ci-dessus à l'aide de System.Reactive
en C#? Est-il possible de le faire facilement tout en gardant toutes les exigences en ce qui concerne INotifyPropertyChanged
, les valeurs null sur le moyen et la valeur par défaut? Vous pouvez faire tous les sane hypothèses en cas de besoin.