views:

302

answers:

2

I have two types of text that need to follow similar coloring rules based on an enumeration:

 public enum Modes
 {
   A,
   B,
   C
 }

A Style with DataTrigger markup is used to colorize:

      <Style TargetType="SEE BELOW" x:Key="Coloring">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=.}" Value="A">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=.}" Value="B">
                    <Setter Property="Foreground" Value="Green" />
                </DataTrigger>
               <DataTrigger Binding="{Binding Path=.}" Value="C">
                    <Setter Property="Foreground" Value="Blue" />
                </DataTrigger>
            </Style.Triggers>
        </Style>

One use scenario is a System.Windows.Documents.Hyperlink with a nested System.Windows.Controls.TextBlock:

<Hyperlink><TextBlock/></Hyperlink>

and the other is just a simple TextBlock:

<TextBlock Style="{StaticResource Coloring}" Text="yada"/>

I can, of course, style both TextBlock elements:

<TextBlock Style="{StaticResource Coloring}" Text="yada"/>
<Hyperlink><TextBlock Style="{StaticResource Coloring}"/></Hyperlink>

but that fails to style the underline of the Hyperlink case.

If I try to style across both types:

<TextBlock Style="{StaticResource Coloring}" Text="yada"/>
<Hyperlink Style="{StaticResource Coloring}"><TextBlock/></Hyperlink>

Then the styling fails, as there is (apparently) no common ancestor type for use in the TargetType attribute of the Style.

Since this is suppposed to ultimately be a configurable thing, the goal is to have an XAML document that defines a mode to color mapping for these text blocks. Thus I am reluctant to have two redundant styles (one for Hyperlink and one for TextBlock) that define the same mapping.

So...the question: How can I consistently style both cases without redundant Style XAML blocks?

+2  A: 

You can force Hyperlinks to have the same foreground colour as their parent TextBlocks by binding them within the style itself, like this:

<Style TargetType="TextBlock" x:Key="Coloring">
        <Style.Resources>
            <Style TargetType="Hyperlink">
                <Setter Property="Foreground" Value="{Binding Foreground,RelativeSource={RelativeSource FindAncestor,AncestorType=TextBlock}}"/>
            </Style>
        </Style.Resources>
            <Setter Property="Foreground" Value="Orange"/>
        <Style.Triggers>
        <DataTrigger Binding="{Binding Path=.}" Value="A">
            <Setter Property="Foreground" Value="Red" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=.}" Value="B">
            <Setter Property="Foreground" Value="Green" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=.}" Value="C">
            <Setter Property="Foreground" Value="Blue" />
        </DataTrigger>
    </Style.Triggers>
</Style>

In this example I've added a setter to make the default foreground Orange, just for testing purposes.

Matt Hamilton
Thanks. So many ways to accomplish things in WPF. I think I have enough to move forward now.
ee
A: 

After posting, I realized another approach. I was forcing the Hyperlink with nested TextBlock scenario. If I were to wrap the the Hyperlink in a TextBlock:

<TextBlock Style="{StaticResource Coloring}"><Hyperlink><TextBlock/></HyperLink></TextBlock>

Then both my cases collapse to a TextBlock styling. (In combination with the solution above)

ee