How do you conditionally bind data?

1.3k Views Asked by At

How do I conditionally bind data to a combo box? I have a combo box that by default should display an ID. However, if the user checks a check box then the display should display both the ID and a NAME. For example, "OO1: Sam". I have the default ID displaying correctly. I'm just not sure how to get both the ID and the NAME to display based on the "IsChecked" state of the check box.

WPF and C# .Net 3.5

2

There are 2 best solutions below

4
On BEST ANSWER

Here's one way, using a style on the ComboBox with triggers to set the ItemTemplate dynamically:

Edit: Changing the style into a resource. Note that this is still binding to the CheckBox directly using element binding - if you want it to be more flexible you could bind the CheckBox's IsChecked property to a property of your ViewModel and rely on that changing rather than IsChecked.

Let's move the style into the Resources section of our Window:

<Window.Resources>
    <Style x:Key="myStyle" TargetType="ComboBox">
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Name}" />
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <DataTrigger Binding="{Binding IsChecked,ElementName=chk}" Value="True">
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding ID}" />
                                <TextBlock Text=": " />
                                <TextBlock Text="{Binding Name}" />
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

Now we define the CheckBox and a couple of ComboBoxes that rely on it:

<CheckBox x:Name="chk" Content="Click Me" />

<ComboBox ItemsSource="{Binding}" Style="{StaticResource myStyle}" />

<ComboBox ItemsSource="{Binding}" Style="{StaticResource myStyle}" />
0
On

I would do that in the ViewModel. You could have a viewmodel for your combo box items, another one for whatever screen the checkbox lives on, and some way for the checkbox viewmodel to tell the item viewmodels when its value has changed. The item viewmodel then has conditional logic in its Text property (or whatever you call it), and implements the usual INotifyPropertyChanged pattern to notify the UI when its text has changed.

The benefit: this way you can write unit tests for this behavior. (And if it's worth putting in, it's worth writing unit tests for.)