3

我正在构建 Windows Phone 应用程序,并创建了一个自定义图标按钮,该按钮将被反复使用。该按钮看起来很像下图:

按钮样机

为了尝试遵循 DRY(不要重复自己)原则,我创建了一个基本上继承自的类,Button并添加了一个ControlTemplate名为IconTemplate

Text为简洁起见,我省略了有关属性的部分

public class IconButton : Button
{
    public static readonly DependencyProperty IconTemplateProperty =
                DependencyProperty.Register(
                    "IconTemplate",
                    typeof(ControlTemplate),
                    typeof(IconButton),
                    null);

    public ControlTemplate IconTemplate
    {
        get { return (ControlTemplate)GetValue(IconTemplateProperty); }
        set { SetValue(IconTemplateProperty, value); }
    }
}

创建类后,我进行了Resource调用Generic.xaml,将一些样式应用于此类。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:c="clr-namespace:PiadasEngracadas.Controls"

    <Style TargetType="c:IconButton">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
        <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
        <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
        <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
        <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="c:IconButton">
                    <Grid Background="{TemplateBinding Background}" x:Name="ButtonBackground">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver"/>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="IconTemplateContainer">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
                                         </ObjectAnimationUsingKeyFrames>
                                         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
                                          </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="IconTemplateContainer">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentControl x:Name="IconTemplateContainer"
                                        Template="{TemplateBinding IconTemplate}" />
                        <TextBlock VerticalAlignment="Bottom"
                                   HorizontalAlignment="Right"
                                   Margin="{StaticResource PhoneHorizontalMargin}"
                                   FontFamily="{StaticResource PhoneFontFamilyLight}"
                                   Text="{TemplateBinding Text}" />
                    </Grid>              
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

所以我可以简单地创建这样的按钮,并且外观是正确的。

<c:IconButton Text="Some Text"
              IconTemplate="{StaticResource IconsButtons.Sleepy}" />

问题是我想Path's Stroke在用户点击按钮时更改颜色。

因为我要一遍又一遍地使用这个按钮,所以我认为拥有另一个属性可能会很有价值,它可以在点击按钮时定义新的笔触颜色。就像是:

<c:IconButton Text="Some Text"
              TappedColor="#123456" // New property
              IconTemplate="{StaticResource IconsButtons.Sleepy}" />

但问题是我不知道如何更改 .PathTemplate(?) 的颜色ContentControl。我在想这样的事情:

<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="(IconTemplateContainer).(Template).(Stroke)">

我知道这种语法是完全错误的,但我想知道是否有人可以帮助我实现我的目标。

PS:我将所有Paths 包装在 a 中,ControlTemplate因为Path直接使用并将其绑定到的Content属性ContentControl在 WP 上不起作用(或者至少我不够聪明,无法使其工作)。即使在这种情况下,我将如何更改ContentControls Content for a certainVisualState` 中对象的属性?

更新

代码ControlTemplate如下

<ControlTemplate x:Key="IconsButtons.Sleepy">
    <Path Data="M32.000099,44.658999C36.566562,44.658999 39.162999,47.058804 ...."
          Stretch="Uniform"
          Fill="#FFFFFFFF"
          Width="26"
          Height="26"
          Margin="0"
          RenderTransformOrigin="0.5,0.5">
        <Path.RenderTransform>
            <TransformGroup>
                <TransformGroup.Children>
                    <RotateTransform Angle="0" />
                    <ScaleTransform ScaleX="1" ScaleY="1" />
                </TransformGroup.Children>
            </TransformGroup>
        </Path.RenderTransform>
    </Path>
</ControlTemplate>
4

1 回答 1

2

您可以对 IconButton 的前景色的路径的笔触颜色执行 TemplateBinding。然后你可以改变 IconButton 的前景色,它会改变路径颜色:Stroke="{TemplateBinding Foreground}"

于 2013-10-15T15:47:32.093 回答