Question

I have a ListView control with a list of system messages in it, and a corresponding "action" button that will help my user resolve the message:

Example of problem

If the message is an error message, I want the Foreground of the text and the action button (the [more...] part) to turn red. As you can see, it's not doing that.

I'm using a Style.Trigger bound to the message data's Severity to set the Foreground. This works fine for the TextBlock in the DataTemplate, but fails to affect the Button in that Template. My XAML looks like this:

   <ListView x:Name="ImageCenterStatus" Background="{DynamicResource SC.ControlBrush}" Margin="10,22,10,0"  FontSize="12" Grid.Column="1" ClipToBounds="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock TextWrapping="WrapWithOverflow" cal:Message.Attach="[Event MouseUp] = [Action DoStatusAction($dataContext)]" Text="{Binding Path=DisplayedMessage}"/>
                        <Button x:Name="ActionButton" Content="{Binding Path=DisplayedActionLabel}" FontSize="12" cal:Message.Attach="DoStatusAction($dataContext)" Style="{DynamicResource SC.ActionButtonHack}"></Button>
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=Severity}" Value="Warning">
                            <Setter Property="Foreground" Value="#FFCE7A16"  />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=Severity}" Value="Error">
                            <Setter Property="Foreground" Value="#FFD13636"  />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

The Button has its own Style, SC.ActionButtonHack, but I am very careful not to override the Foreground anywhere that style:

            <Style x:Key="SC.ActionButtonHack" TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Why does the TextBlock in the DataTemplate respond to the Foreground change in the Trigger, but not the Button? What do I need to do to get the button to respect the Foreground change?

Was it helpful?

Solution

Bind TextElement.Foreground of ContentPresenter to ListViewItem's foreground to get it work:

<Style x:Key="SC.ActionButtonHack" TargetType="{x:Type Button}">
    <Setter Property="Template">
       <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
              <ContentPresenter x:Name="contentPresenter"
                                TextElement.Foreground="{Binding Foreground, 
                                RelativeSource={RelativeSource Mode=FindAncestor,
                                                  AncestorType=ListViewItem}}"
                                HorizontalAlignment="Center"
                               VerticalAlignment="Center" Margin="0"/>
          </ControlTemplate>
       </Setter.Value>
    </Setter>
</Style>

OR

Either bind it on Button itself:

<Button x:Name="ActionButton"
        Foreground="{Binding Foreground, RelativeSource={RelativeSource 
                         Mode=FindAncestor, AncestorType=ListViewItem}}"
        Content="{Binding Path=Name}" FontSize="12"
        Style="{DynamicResource SC.ActionButtonHack}"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top