将样式应用于ContentPresenter内的Path(BasedOn不起作用!) [英] Applying style to Path inside ContentPresenter (BasedOn not working!)

查看:55
本文介绍了将样式应用于ContentPresenter内的Path(BasedOn不起作用!)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法将MouseOver样式应用于ContentPresenter内的路径.

I am unable to apply a MouseOver style to a Path inside a ContentPresenter.

我有一个包含ContentPresenter的Button样式:

I have a Button style containing a 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 Path:

<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>

我还有一个资源图标文件,其中包含带有路径的Viewbox:

I also have a resource file for icons with a Viewbox that contains a 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>

最后,我创建一个按钮并将Viewbox资源分配给Content:

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

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

使用"BasedOn"为ContentPresenter的内容设置样式是一种我在这里找到的技术:

The use of "BasedOn" to style the contents of the ContentPresenter is a technique that I found here:

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

但是,它对我不起作用...我花了很多时间试图解决这个问题!

However, it doesn't work for me... I've spent many hours trying to figure this out!

有什么想法吗?

谢谢!

基于Mackho的出色回答,确定,这是我的最终XAML.

OK based upon Mackho's excellent answer, here is my final XAML.

我还为IsPressed添加了DataTriggeer,效果很好!

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

我希望这可以帮助某人...

I hope this helps someone...

首先,样式:

<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>

接下来,图标本身:

<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>

然后是模板:

<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, let's place a few buttons that use the template 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>

推荐答案

问题不在于"BasedOn",您可以定义整个样式而不是使用baseon,但仍然无法使用.您只需要在ControlTemplate资源中移动阶梯即可,它肯定可以工作

The problem is not about "BasedOn", you can define the entire style instead of use baseon and it still doesn't work. You just need to move your stile in 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>

说实话,我不知道为什么它在ContentPresenter资源中不起作用:)

To be honest I don't know why It is not working inside ContentPresenter resources :)

修改

如果要基于按钮鼠标悬停来更改路径样式,则需要将ismouseover属性绑定到按钮一并在路径集合内移动样式,请参见下文

If you want to change path style based on button mouseover you need to bind ismouseover property to the button one and move your style inside 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 to know, it's pretty useless to base a style to another and add nothing, you could use:

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

希望这会有所帮助

这篇关于将样式应用于ContentPresenter内的Path(BasedOn不起作用!)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆