Jeremy White
Jeremy White

Reputation: 901

How do I apply a style resource to a usercontrol where that style uses triggers to apply templates?

I apologize if this is an easy question, but I have been trying to get this to work all day and I can't seem to figure something out that is fairly obvious probably.

I have a user control with a custom dependency property "Flipped".

In my resource I have a Style with two triggers defined, that set the template of the control to two different values depending on if 'Flipped' is true of false.

Now, what syntax do I use to apply the style to this user control I am creating?

Putting Style="{StaticResource EventStyle}" in the header of the UserControl won't work.

Here is what I have so far :

<UserControl x:Class="XDPClient.Controls.EventMarkerControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:Controls="clr-namespace:XDPClient.Controls" 
         mc:Ignorable="d" 
         d:DesignHeight="513" d:DesignWidth="695">

<UserControl.Resources>
    <!-- Draw the user control right side up with this template -->
    <ControlTemplate x:Key="Up" TargetType="{x:Type Controls:EventMarkerControl}">
        <Grid>
            <!-- Outline grid  -->
            <Path Stretch="Fill" Fill="#FFFFFFFF" Stroke="#FF6800FF" StrokeThickness="3" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="4" Name="rect2985" RenderTransformOrigin="0,0">
                <Path.Data>
                    <PathGeometry FillRule="Nonzero"   Figures="M 0,250 L 0,50 L 150,50 L 200,-0.96 L 250,50 L 400,50 L 400,250 L 0,250z" />
                </Path.Data>
            </Path>

            <!-- Placement of the content -->
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*" />
                    <RowDefinition Height="4*" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="1" Margin="3">
                    <ContentPresenter Grid.Row="1" 
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"        
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Grid>
            </Grid>

            <Grid.BitmapEffect>
                <DropShadowBitmapEffect />
            </Grid.BitmapEffect>
        </Grid>
    </ControlTemplate>

    <!-- Draw the user control flipped with this template -->
    <ControlTemplate x:Key="Down" TargetType="{x:Type Controls:EventMarkerControl}">
        <Grid>
            <!-- Outline grid  -->
            <Path Stretch="Fill" Fill="#FFFFFFFF" Stroke="#FF6800FF" StrokeThickness="3" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="4" Name="rect2985" RenderTransformOrigin="0,0">
                <Path.Data>
                    <PathGeometry FillRule="Nonzero"   Figures="M 0,250 L 0,50 L 150,50 L 200,-0.96 L 250,50 L 400,50 L 400,250 L 0,250z" />

                </Path.Data>
                <Path.RenderTransform>
                    <ScaleTransform ScaleX="-1" />
                </Path.RenderTransform>
            </Path>

            <!-- Placement of the content -->
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*" />
                    <RowDefinition Height="4*" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="1" Margin="3">
                    <ContentPresenter Grid.Row="1" 
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"        
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Grid>
            </Grid>

            <Grid.BitmapEffect>
                <DropShadowBitmapEffect />
            </Grid.BitmapEffect>
        </Grid>
    </ControlTemplate>

    <Style x:Key="EventStyle" TargetType="{x:Type Controls:EventMarkerControl}">
        <Style.Triggers>
            <Trigger Property="Flipped" Value="false">
                <Setter Property="Template" Value="{StaticResource Up}" />
            </Trigger>
            <Trigger Property="Flipped" Value="true">
                <Setter Property="Template" Value="{StaticResource Down}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

Upvotes: 1

Views: 146

Answers (1)

hbarck
hbarck

Reputation: 2944

You could try to make the UserControl have one top-level child, like a ContentControl for example, and apply the style to the ContentControl instead. That way, you wouldn't get recursions.

EDIT : The below is from the original questioner......

Here is my attempt to do what you suggest. For some reason my DataTriggers never apply the template.... not sure what I did wrong here.

Here is the whole XAML trying it with a contained ContentControl :

<UserControl x:Class="XDPClient.Controls.EventMarkerControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:Controls="clr-namespace:XDPClient.Controls" mc:Ignorable="d" 
         d:DesignHeight="513" d:DesignWidth="695"
         x:Name="uc">

<UserControl.Resources>
    <!-- Draw the user control right side up with this template -->
    <ControlTemplate x:Key="Up" TargetType="{x:Type ContentControl}">
        <Grid>
            <!-- Outline grid  -->
            <Path Stretch="Fill" Fill="#FFFFFFFF" Stroke="#FF6800FF" StrokeThickness="3" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="4" Name="rect2985" RenderTransformOrigin="0,0">
                <Path.Data>
                    <PathGeometry FillRule="Nonzero"   Figures="M 0,250 L 0,50 L 150,50 L 200,-0.96 L 250,50 L 400,50 L 400,250 L 0,250z" />
                </Path.Data>
            </Path>

            <!-- Placement of the content -->
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*" />
                    <RowDefinition Height="4*" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="1" Margin="3">
                    <ContentPresenter Grid.Row="1" 
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"        
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Grid>
            </Grid>

            <Grid.BitmapEffect>
                <DropShadowBitmapEffect />
            </Grid.BitmapEffect>
        </Grid>
    </ControlTemplate>

    <!-- Draw the user control flipped with this template -->
    <ControlTemplate x:Key="Down" TargetType="{x:Type ContentControl}">
        <Grid>
            <!-- Outline grid  -->
            <Path Stretch="Fill" Fill="#FFFFFFFF" Stroke="#FF6800FF" StrokeThickness="3" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="4" Name="rect2985" RenderTransformOrigin="0,0">
                <Path.Data>
                    <PathGeometry FillRule="Nonzero"   Figures="M 0,250 L 0,50 L 150,50 L 200,-0.96 L 250,50 L 400,50 L 400,250 L 0,250z" />

                </Path.Data>
                <Path.RenderTransform>
                    <ScaleTransform ScaleX="-1" />
                </Path.RenderTransform>
            </Path>

            <!-- Placement of the content -->
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*" />
                    <RowDefinition Height="4*" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="1" Margin="3">
                    <ContentPresenter Grid.Row="1" 
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"        
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Grid>
            </Grid>

            <Grid.BitmapEffect>
                <DropShadowBitmapEffect />
            </Grid.BitmapEffect>
        </Grid>
    </ControlTemplate>


</UserControl.Resources>

<ContentControl x:Name="ContentControl" >
    <!-- Style for the content control -->
    <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
            <Style.Triggers>
                <DataTrigger Value="False" Binding="{Binding ElementName=uc, Path=Flipped}">
                    <Setter Property="ContentControl.Template" Value="{StaticResource Up}" />
                </DataTrigger>
                <DataTrigger Value="True" Binding="{Binding ElementName=uc, Path=Flipped}">
                    <Setter Property="ContentControl.Template" Value="{StaticResource Down}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>
</UserControl>

If I apply the style by hand like this :

    <ContentControl x:Name="ContentControl" Template="{StaticResource Up}">

It looks good! It's just that my datatriggers are not firing on the value of "Flipped"

Upvotes: 1

Related Questions