1

我对 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”类型

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

提前致谢。

4

2 回答 2

1

尽管直接通过 StaticResource 传递资源并不可靠,但 XAML 元素通常可以进一步分解为可重用的部分。如果您查看PathGeometry 类声明,您会注意到它具有:

[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在需要时将其应用于 a:

<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

于 2013-07-26T00:35:59.730 回答
0

您不能像这样将 aStaticResource用作实际资源(此处:)的“代理” PathGeometry

您可以做的是将每个移动PathGeometry到其相应的<Style.Resources>部分。因此,您不会有任何称为“X_Sign”或“Min_Sign”的 PathGeometries - 只有两个称为“geoPath”:

...

<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>
于 2013-07-25T22:28:05.723 回答