我正在构建 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}" />
但问题是我不知道如何更改 .Path
的Template
(?) 的颜色ContentControl
。我在想这样的事情:
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="(IconTemplateContainer).(Template).(Stroke)">
我知道这种语法是完全错误的,但我想知道是否有人可以帮助我实现我的目标。
PS:我将所有Path
s 包装在 a 中,ControlTemplate
因为Path
直接使用并将其绑定到的Content
属性ContentControl
在 WP 上不起作用(或者至少我不够聪明,无法使其工作)。即使在这种情况下,我将如何更改ContentControl
s Content for a certain
VisualState` 中对象的属性?
更新
代码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>