Applying style to a path inside ContentPresenter (BasedOn doesn't work!)

I cannot apply the MouseOver style to the outline inside ContentPresenter.

I have a Button style containing ContentPresenter:

<Style x:Key="ContentButton" TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}"> <ContentPresenter.Resources> <Style TargetType="{x:Type Path}" BasedOn="{StaticResource ContentButtonPathStyle}"/> </ContentPresenter.Resources> </ContentPresenter> 

Here is a style, so I can have a rollover effect on the way:

 <Style x:Key="ContentButtonPathStyle" TargetType="{x:Type Path}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Fill" Value="#FF00FF10"/> <Setter Property="Stroke" Value="Red"/> <Setter Property="StrokeThickness" Value="6"/> </Trigger> </Style.Triggers> <Setter Property="Stroke" Value="Red"/> <Setter Property="Fill"> <Setter.Value> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFB4B3E7" Offset="0"/> <GradientStop Color="#FF0800FF" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> 

I also have a resource file for icons with the Viewbox, which contains the path:

 <Viewbox x:Key="MyIcon"> <Grid> <Path Data="M78,296 L37.5,306.5 45.5,354.5 123.5,343.5 z" /> </Grid> </Viewbox> 

And finally, I create a button and assign the Viewbox resource to Content:

 <Button Style="{DynamicResource ContentButton}"> <ContentPresenter Content="{DynamicResource MyIcon}"/> </Button> 

Using "BasedOn" to style the content of a ContentPresenter is the method I found here:

http://social.msdn.microsoft.com/forums/en-US/wpf/thread/412b1747-60e9-4b9a-8f8f-bd56f3aff875/

However, this does not work for me ... I spent many hours trying to figure it out!

Any ideas?

Thanks!


OK, based on Makho's excellent answer, here is my last XAML.

I also added a DataTriggeer for IsPressed, which works great!

I hope this helps someone ...

First, style:

 <Style x:Key="ContentButtonPathStyle" TargetType="{x:Type Path}"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsMouseOver}" Value="True"> <Setter Property="Fill" Value="Yellow"/> <Setter Property="Stroke" Value="Blue"/> </DataTrigger> <DataTrigger Binding="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsPressed}" Value="True"> <Setter Property="Fill" Value="Red"/> <Setter Property="Stroke" Value="Black"/> </DataTrigger> </Style.Triggers> <Setter Property="Fill" Value="Green"/> <Setter Property="Stroke" Value="Red"/> </Style> 

Next, the icon itself:

 <Viewbox Stretch="Fill" x:Shared="False" x:Key="MyIcon"> <Path StrokeThickness="6" Data="M160.26077,0.5 L196.5,36.739223 232.73923,0.5 251.12399,18.884777 214.88478,55.124001 251.12399,91.363222 232.73923,109.748 196.5,73.508779 160.26077,109.748 141.87601,91.363222 178.11522,55.124001 141.87601,18.884777 z" Stretch="Fill"/> </Viewbox> 

Then the template:

 <Style x:Key="ContentButton" TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate.Resources> <Style TargetType="{x:Type Path}" BasedOn="{StaticResource ContentButtonPathStyle}"/> </ControlTemplate.Resources> <Grid Background="Transparent"><ContentPresenter /></Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> 

And finally, put a few buttons that use a pattern and style:

 <Grid> <Button Style="{DynamicResource ContentButton}" HorizontalAlignment="Left" Width="128" Height="128" VerticalAlignment="Top" Margin="85.5,87,0,0"> <ContentPresenter Content="{DynamicResource MyIcon}" d:IsLocked="True"/> </Button> <Button Style="{DynamicResource ContentButton}" Height="64" VerticalAlignment="Top" Margin="0,87,204.5,0" HorizontalAlignment="Right" Width="64"> <ContentPresenter Content="{DynamicResource MyIcon}" d:IsLocked="True"/> </Button> <Button Style="{DynamicResource ContentButton}" Height="96" VerticalAlignment="Bottom" Margin="234,0,0,66.5" HorizontalAlignment="Left" Width="96"> <ContentPresenter Content="{DynamicResource MyIcon}" d:IsLocked="True"/> </Button> <Button Style="{DynamicResource ContentButton}" Height="32" VerticalAlignment="Bottom" Margin="0,0,138.5,130.5" HorizontalAlignment="Right" Width="32"> <ContentPresenter Content="{DynamicResource MyIcon}" d:IsLocked="True"/> </Button> </Grid> 
+6
source share
1 answer

The problem is not "BasedOn", you can define the whole style instead of using baseon, and it still doesn't work. You just need to move your style to ControlTemplate resources, and it will work for sure.

  <Style x:Key="ContentButton" TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate.Resources> <Style TargetType="{x:Type Path}" BasedOn="{StaticResource ContentButtonPathStyle}"/> </ControlTemplate.Resources> <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}"> </ContentPresenter> </ControlTemplate> </Setter.Value> </Setter> </Style> 

Honestly, I do not know why it does not work inside ContentPresenter resources :)

Edit

If you want to change the style of the path based on the mouse button, you need to bind the ismouseover property to one button and move your style inside the path collection, see below

  <Style x:Key="ContentButtonPathStyle" TargetType="{x:Type Path}"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsMouseOver}" Value="True"> <Setter Property="Fill" Value="#FF00FF10"/> <Setter Property="Stroke" Value="Red"/> <Setter Property="StrokeThickness" Value="6"/> </DataTrigger> </Style.Triggers> <Setter Property="Stroke" Value="Red"/> <Setter Property="Fill"> <Setter.Value> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFB4B3E7" Offset="0"/> <GradientStop Color="#FF0800FF" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> <Style x:Key="ContentButton" TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <ContentPresenter x:Name="contentPresenter" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Viewbox x:Key="MyIcon"> <Grid Background="Transparent"> <Grid.Resources> <Style TargetType="{x:Type Path}" BasedOn="{StaticResource ContentButtonPathStyle}"/> </Grid.Resources> <Path Data="M78,296 L37.5,306.5 45.5,354.5 123.5,343.5 z" /> </Grid> </Viewbox> 

And just for you, it's pretty useless to base a style on another and not add anything, you could use:

 <Path Style="{StaticResource ContentButtonPathStyle}" Data="...." /> 

Hope this helps

+7
source

Source: https://habr.com/ru/post/903249/


All Articles