0
votes

I have a status bar that, via data binding and triggers, shows whether a user is connected to a server. I'm styling two different elements to achieve this: the actual StatusBarItem to set a colored background (red, green, yellow), and a TextBlock inside to display the text ("Not Connected", "Connected" etc.) As I'm doing this in XAML, I have to duplicate the DataTrigger logic across two styles (to update the background in one and text in another), like so:

<StatusBarItem Grid.Column="0" HorizontalAlignment="Left" Padding="10,0,10,0">
    <StatusBarItem.Style>
        <Style TargetType="StatusBarItem">
            <Setter Property="Background" Value="Red" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.NotConnected}">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.Connected}">
                    <Setter Property="Background" Value="Green" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.OfflineMode}">
                    <Setter Property="Background" Value="Goldenrod" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StatusBarItem.Style>
    <TextBlock Width="Auto" Height="Auto">
        <TextBlock.Style>
            <Style TargetType="TextBlock">
                <Setter Property="Text" Value="Not Connected" />
                <Setter Property="Foreground" Value="White" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.NotConnected}">
                        <Setter Property="Text" Value="Not Connected" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.Connected}">
                        <Setter Property="Text" Value="Connected to Perforce" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.OfflineMode}">
                        <Setter Property="Text" Value="Offline Mode" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</StatusBarItem>

Question: is there a way to compress this code and not duplicate the DataTrigger logic?

Please note that I'm not interested in solutions that make the TextBlock fill out the entire StatusBarItem. Sure, that would solve this particular issue (I'd just style the TextBlock for both background color and text). But it doesn't address the issue at large (duplicate code that has to be updated in two places).

1

1 Answers

1
votes

In this particular case you could set the Content property using the DataTriggers in the StatusBarItem style instead of using an explicit TextBlock as the Content:

<StatusBarItem Grid.Column="0" HorizontalAlignment="Left" Padding="10,0,10,0">
    <StatusBarItem.Style>
        <Style TargetType="StatusBarItem">
            <Setter Property="Background" Value="Red" />
            <Setter Property="Content" Value="Not Connected" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.NotConnected}">
                    <Setter Property="Background" Value="Red" />
                    <Setter Property="Content" Value="Not Connected" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.Connected}">
                    <Setter Property="Background" Value="Green" />
                    <Setter Property="Content" Value="Connected to Perforce" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.OfflineMode}">
                    <Setter Property="Background" Value="Goldenrod" />
                    <Setter Property="Content" Value="Offline mode" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StatusBarItem.Style>
</StatusBarItem>

Another option would be to define your own custom ControlTemplate for the StatusBarItem and use ControlTemplate.Triggers to change the background and the text in one place.