Search code examples
c#wpfxamlmvvm

How do I control the number of textboxes displayed in a listbox based on the state of a checkbox using MVVM


I am collecting messages from a com port. When the message is received a time stamp is recorded. I then display the time stamp followed by the message. It looks like:

01/02/2022 13:14:15.123  00 48 B4 68 33

I want to add a checkbox that will show the timestamp when checked, and just the message when unchecked.

My XAML for displaying the timestamp and message:

        <ListBox Grid.Row="1" x:Name="MessageList" Margin="10" ItemsSource="{Binding Path=SDIMessages}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding RecivedTime, StringFormat=dd-MM-yyyy HH:mm:ss.fff}"/>
                        <TextBlock Text="{Binding Message}" Margin="10,0,0,0"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

My code for the checkbox

<CheckBox Grid.Row="0" VerticalAlignment="Bottom" Margin="10,0,0,0" IsChecked="{Binding ShowTimeStamp, Mode=TwoWay}" Content="Display Time Stamp"/>

Currently I have the binding for ShowTimeStamp working correctly. How do I hide the TimeRecived? I am still learning C#, XAML and MVVM. I believe I need to use a datatrigger somehow but how do I make the trigger from the checkbox affect a listbox?


Solution

  • you can give checkbox a name ("CheckTimeStamp") and bind TextBlocks Visibility directly to IsChecked property (without involving view model) using BooleanToVisibilityConverter:

    <CheckBox Grid.Row="0" Name="CheckTimeStamp" VerticalAlignment="Bottom" Margin="10,0,0,0" IsChecked="{Binding ShowTimeStamp, Mode=TwoWay}" Content="Display Time Stamp"/>
    
    <ListBox Grid.Row="1" x:Name="MessageList" Margin="10" ItemsSource="{Binding Path=SDIMessages}">
        <ListBox.Resources>
            <BooleanToVisibilityConverter x:Key="boolToVisibility"/>
        </ListBox.Resources>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding RecivedTime, StringFormat=dd-MM-yyyy HH:mm:ss.fff}" 
                               Visibility="{Binding ElementName=CheckTimeStamp, Path=IsChecked, Converter={StaticResource boolToVisibility}}"/>
                    <TextBlock Text="{Binding Message}" Margin="10,0,0,0"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>