Search code examples
c#wpftextblock

WPF Add text to TextBlock based on property


I have a ListView with a column that shows the state two letter appreviation. Based on the value of a Boolean property (HasWorkState) I would like to add parenthesis around the state abbreviation when HasWorkState = false.

For instance:

  • HasWorkState = true display OH
  • HasWorkState = false display (OH)

The state abbreviation is displayed in a GridViewColumn:

<!-- Work State -->
<GridViewColumn Width="{Binding ActualWidth, 
                          RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, 
                          Converter={StaticResource MathConverter}, ConverterParameter=(x/10)*0.5}">
    <GridViewColumn.Header>
        <GridViewColumnHeader Content=" State"
                              HorizontalContentAlignment="Left" />
    </GridViewColumn.Header>
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding WorkState}"
                       Style="{StaticResource StateStyle}" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

To this GridViewColumn I have applied this style:

<!-- Highlight missing work states -->
<Style x:Key="StateStyle" TargetType="TextBlock">
    <Style.Triggers>
        <DataTrigger Binding="{Binding HasWorkState}" Value="False">
            <Setter Property="Text" Value="{Binding StringFormat=({0})}" />
            <Setter Property="ToolTip" Value="Work location unspecified. Using residence state." />
        </DataTrigger>
    </Style.Triggers>
</Style>

I know this style is being applied correctly as the ToolTip is being displayed when HasWorkState = false. I just need to know how to add the parenthesis. What I currently have for the Text value setter is not working.


Solution

  • You've got a solution, but it's worth knowing why you had the problem: Because you're setting Text with an attribute on the TextBlock element, the style can't override that. If you used a style setter to apply the default {Binding WorkState}, the style would be able to override it.

    I prefer to keep things like this in the view, so my approach would be this:

    <ContentControl Content="{Binding WorkState}" Style="{StaticResource StateStyle}" />
    

    State style:

    <Style x:Key="StateStyle" TargetType="ContentControl">
        <Style.Triggers>
            <DataTrigger Binding="{Binding HasWorkState}" Value="False">
                <!-- Leave the content alone and just change the format string -->
                <Setter Property="ContentStringFormat" Value="({0})" />
    
                <Setter 
                    Property="ToolTip" 
                    Value="Work location unspecified. Using residence state." 
                    />
            </DataTrigger>
        </Style.Triggers>
    </Style>