I am looking for an elegant solution for the following problem.
Let’s assume we have a (View)Model with the following boolean properties:
- Alpha
- Beta
- Gamma
- Delta
Next I have 5 controls on the surface that shall only be visible when a condition based on those properties are met. Of course, as soon as one of those properties is updated the change should be propagated immediatelly:
- ControlA -> Alpha && ( Beta || Gamma )
- ControlB -> Delta
- ControlC -> Delta || Beta
- ControlD -> Gamma && Alpha && Delta
- ControlE -> Alpha || Gamma
The only solution I came up with so far is using MultiValueConverters.
Example for ControlA:
<ControlA>
<ControlA.Visibility>
<MultiBinding Converter={StaticResource ControlAVisibilityConverter}>
<Binding Path="Alpha"/>
<Binding Path="Beta"/>
<Binding Path="Gamma"/>
</MultiBinding>
</ControlA.Visibility>
</ControlA>
This ControlAVisibilityConverter checks for condition “Alpha && ( Beta || Gamma )” and returns the appropriate value.
It does work.. well.. but maybe you can come up with a more elegant solution?
Thank you,
TwinHabit
Writing a converter for each rule puts your business logic two places in this case (in the converter and the view model).
I suggest creating a property/flag for each control in your ViewModel with INotifyPropertyChanged events to decide whether the control is visible (or other behaviour).
Note, that when you look at my viewmodel (below) you will see that I expose properties of type bool and Visibilty.
If you need to use the property as a general rule use bool and a DataTrigger.
If you only need to control visibility you can bind to Visibility directly:
UPDATE:
Because of the comment by @Wallstreet Programmer, I added another option to use a BooleanVisibilityConverter. I updated the fifth control below to reflect how to use a converter. I added the code for the converter at the bottom.
Here is a test Window in XAML:
Here is the ViewModel:
Here is the converter: