Silverlight - 如何从VisualState影响属性

时间:2011-08-15 20:37:12

标签: silverlight xaml

我有以下代码:

<Style x:Key="GoButton" TargetType="Button">
    <Setter Property="Background" Value="#FF2B832C"/>
    <Setter Property="Foreground" Value="#FFfdf7bd"/>
    <Setter Property="FontSize" Value="30" />
    <Setter Property="Padding" Value="3"/>
    <Setter Property="BorderThickness" Value="3"/>
    <Setter Property="BorderBrush">
        <Setter.Value>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientStop Color="#4d9e41" Offset="0" />
                <GradientStop Color="#294c22" Offset="1" />
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                            </VisualState>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="FontSize" To="35" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" CornerRadius="5">
                        <Grid Background="{TemplateBinding Background}" Margin="0">
                            <Border x:Name="BackgroundAnimation" Background="#FF448DCA" CornerRadius="5" Opacity="0"/>
                            <Rectangle x:Name="BackgroundGradient" RadiusX="5" RadiusY="5">
                                <Rectangle.Fill>
                                    <LinearGradientBrush EndPoint="0.8,1" StartPoint="0,0">
                                        <GradientStop Color="#66b04d" Offset="0"/>
                                        <GradientStop Color="#66b04d" Offset="0.375"/>
                                        <GradientStop Color="#2d822d" Offset="0.625"/>
                                        <GradientStop Color="#2d822d" Offset="1"/>
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                        </Grid>
                    </Border>
                    <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    <Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0" RadiusY="6" RadiusX="6"/>
                    <Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" RadiusY="5" RadiusX="5" Stroke="#FF6DBDD1" StrokeThickness="1"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我想在用户MouseOver按钮时更改FontSize。但是这段代码不起作用,如果我删除字符串,但没有我的动画,它就可以工作:

<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="FontSize" To="35" />

如何正确地做到这一点?

1 个答案:

答案 0 :(得分:3)

我通过用

替换模板中的<ContentPresenter>让你的动画工作
<ContentControl x:Name="nestedContentControl" ContentTemplate="{TemplateBinding ContentTemplate}" 
                Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}"
                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />

然后将MouseOver动画的Storyboard.TargetName设置为nestedContentControl

问题似乎是为Storyboard.TargetName提供了一个值。虽然您可以访问模板应用的控件的名称(即使用此模板的Button),但Storyboard似乎无法访问模板化控件。因此,我们在模板中嵌套另一个ContentControl(Button本身就是一个ContentControl)并使用它。

然而,使用另一个ContentControl有其缺点。我必须添加Foreground="{TemplateBinding Foreground}"属性才能获取您正在使用的前景色。您可能需要根据需要使用的其他属性添加更多此类“传递”绑定。

请注意,Focused VisualState上还有一个动画。此动画无法正常工作,因为您尚未为其指定TargetName。我不知道这个建议是什么,因为我不确定你想要实现的目标。

最后,在回答这个问题时,我还发现了a similar question关于动画化父对象的属性的动画。在这种情况下,解决方案似乎是在代码隐藏中连接动画。