如何为相似的按钮使用相同的模板

时间:2013-07-25 21:38:10

标签: wpf controltemplate

我对WPF很新。以下是我尝试使用相同的controlTemplate按钮,它们之间的唯一区别是PathGeometry值。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Shared.xaml" />
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="Button" x:Key="buttonHeader">
        <Setter Property="Width" Value="18" />
        <Setter Property="Height" Value="18" />
        <Setter Property="Cursor" Value="Hand" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border Name="BorderStyle" Background="Transparent" >
                        <Path 
                            x:Name="CheckMark"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Bottom"
                            SnapsToDevicePixels="False" 
                            Stroke="#FF4D4D4D"
                            StrokeThickness="2" StrokeEndLineCap="Flat" StrokeStartLineCap="Flat"
                            Data="{DynamicResource geoPath}">
                        </Path>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="BorderStyle" Property="Background" Value="#B2FFFFFF" />
                            <Setter TargetName="CheckMark" Property="Stroke" Value="#D8727272" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter TargetName="BorderStyle" Property="Background" Value="#B2707070" />
                            <Setter TargetName="CheckMark" Property="Stroke" Value="#D8FFFFFF" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <PathGeometry x:Key="X_Sign">
        <PathFigure StartPoint="0,0">
            <LineSegment Point="10,10"/>
        </PathFigure>
        <PathFigure StartPoint="0,10">
            <LineSegment Point="10,0"/>
        </PathFigure>
    </PathGeometry>

    <PathGeometry x:Key="Min_Sign">
        <PathFigure StartPoint="0,0">
            <LineSegment Point="10,0"/>
        </PathFigure>
    </PathGeometry>

    <Style x:Key="ButtonX" BasedOn="{StaticResource buttonHeader}" TargetType="Button">
        <Style.Resources>
            <StaticResource x:Key="geoPath" ResourceKey="X_Sign"/>
        </Style.Resources>
    </Style>
    <Style x:Key="ButtonXMinimize" BasedOn="{StaticResource buttonHeader}" TargetType="Button">
        <Style.Resources>
            <StaticResource x:Key="geoPath" ResourceKey="Min_Sign"/>
        </Style.Resources>
    </Style>
</ResourceDictionary>

在设计器中我实际上得到了我想要的东西,但是当我尝试运行应用程序时,我得到一个XamlParseException并且innerException是:

  

无法将“System.Windows.Media.PathGeometry”类型的对象强制转换为“System.Windows.ResourceDictionary”

我缺少什么,我该如何解决? 此外,我很高兴知道是否有更好的方法来做到这一点。

提前致谢。

2 个答案:

答案 0 :(得分:1)

虽然直接通过StaticResource传递资源不能可靠地工作,但XAML元素通常可以进一步细分为可重用的部分。如果您查看PathGeometry class declaration,您会发现它有:

[ContentPropertyAttribute("Figures")]

这意味着Figures属性是在XAML中嵌套子项时实际设置的属性。此属性的类型为PathFigureCollection,您的PathFigure元素正在添加到该属性中。这意味着您可以将PathFigureCollection本身存储为资源:

<PathFigureCollection x:Key="XSignFigures">
    <PathFigure StartPoint="0,0">
        <LineSegment Point="10,10"/>
    </PathFigure>
    <PathFigure StartPoint="0,10">
        <LineSegment Point="10,0"/>
    </PathFigure>
</PathFigureCollection>

然后在需要时将其应用到PathGeometry

<Style x:Key="ButtonX" BasedOn="{StaticResource buttonHeader}" TargetType="Button">
    <Style.Resources>
        <PathGeometry x:Key="geoPath" Figures="{StaticResource ResourceKey=XSignFigures}" />
    </Style.Resources>
</Style>

更多信息:http://msdn.microsoft.com/en-us/library/ms788723.aspx#collection_syntax

答案 1 :(得分:0)

您不能将StaticResource用作&#34;代理&#34;对于这样的实际资源(这里:PathGeometry)。

您可以做的是将每个PathGeometry移动到相应的<Style.Resources>部分。因此,您没有任何名为&#34; X_Sign&#34;的PathGeometries。或者&#34; Min_Sign&#34; - 只有两个名为&#34; geoPath&#34;:

...

<Style x:Key="ButtonX" BasedOn="{StaticResource buttonHeader}" TargetType="Button">
    <Style.Resources>
        <!--<StaticResource x:Key="geoPath" ResourceKey="X_Sign"/>-->
        <PathGeometry x:Key="geoPath">
            <PathFigure StartPoint="0,0">
                <LineSegment Point="10,10"/>
            </PathFigure>
            <PathFigure StartPoint="0,10">
                <LineSegment Point="10,0"/>
            </PathFigure>
        </PathGeometry>
    </Style.Resources>
</Style>
<Style x:Key="ButtonXMinimize" BasedOn="{StaticResource buttonHeader}" TargetType="Button">
    <Style.Resources>
        <ResourceDictionary>
            <!--<StaticResource x:Key="geoPath" ResourceKey="Min_Sign"/>-->
            <PathGeometry x:Key="geoPath">
                <PathFigure StartPoint="0,0">
                    <LineSegment Point="10,0"/>
                </PathFigure>
            </PathGeometry>
        </ResourceDictionary>
    </Style.Resources>
</Style>