/ MVVM

Conditional Control

Sometimes there is a need to display different content or the same content differently based on some condition (Boolean property in the view model).

For example, you have a list of items on the screen and you want the user to be able to edit each item inline by pressing a little "Edit" button next to each item. In this case each item can be in two different states: Normal (read-only) and Edit.

Another example would be the case when you have a list of items, but initially that list is empty and in this case instead of the empty list you want to show a message something like "There are no items yet. Press 'Add' to add one.".

If you use Expression Blend you would probably leverage visual states (VisualStateManager) to deal with such scenarios. But I find the syntax of VisualStateManager too cumbersome for such a simple scenario. So I've come up with a simple control that allows me to specify a Boolean condition and two pieces of content - one for False and one for True. Here is how the example with inline editing would look like using this control:

<c:Conditional Condition="{Binding IsInEditMode}">
     
    <c:TrueContent>
        <!-- Here goes the content that should be displayed 
             when the condition is True. In this case the control 
             is in the edit mode, so show the TextBox where the 
             user can enter text -->
        <TextBox Text="{Binding Data}"/>
    </c:TrueContent>
     
    <c:FalseContent>
        <!-- Here goes the content that should be displayed 
             when the condition is False. In this case the 
             control is not in the edit mode, so display just 
             a TextBlock. -->
        <TextBlock Text="{Binding Data}"/>
    </c:FalseContent>           
     
</c:Conditional>

Here, as you can see, the Condition property is bound to the IsInEditMode property on the view model. Whenever this property is set to true we display a TextBox using which the user can edit the data.

The same Conditional control is used as the content of the button that triggers the edit mode. This is because the button should say Edit when IsInEditMode is false and Done otherwise:

<Button Command="{Binding ToggleEditModeCommand}">
    <Button.Content>
        <c:Conditional Condition="{Binding IsInEditMode}"
                       TrueContent="Done"
                       FalseContent="Edit"/>
    </Button.Content>
</Button>

Also it is worth mentioning that you are not obliged to specify both TrueContent and FalseContent. If you specify, for example, only TrueContent the content will be displayed only when the condition is True and nothing will be displayed otherwise. The effect is similar to binding the Visibility property of a control to a Boolean property on the view model with BooleanToVisibilityConverter.

The control is very simple yet very powerful. It gives you a simple way to present conditional content in your applications - from simply changing a button's text to replacing a big part of the screen when some condition changes.

Download the source code and an example

Pavlo Glazkov

Pavlo Glazkov

Programmer. Full stack, with a focus on UI. JavaScript/TypeScript, Angular, Node.js, .NET

Read More