在WPF ControlTemplate中设置两个嵌套的Border元素的动画

时间:2014-07-02 13:42:03

标签: wpf xaml animation controltemplate visualstatemanager

我正在尝试为文本框创建新的ControlTemplate。最后,它应该使用几个自定义状态,这些状态会改变控件的外观。代码片段中的ControlTemplate被剥离到骨骼只是为了说明我的问题。

我想使用两个嵌套边框元素,并以各种视觉状态设置边框和背景颜色的动画。

<Style TargetType="{x:Type TextBox}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="MinHeight" Value="20" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBoxBase}">
                <Border Name="Border" CornerRadius="2" BorderThickness="1" Margin="2">
                    <Border.Background>
                        <SolidColorBrush Color="White" />
                    </Border.Background>
                    <Border.BorderBrush>
                        <SolidColorBrush Color="Black" />
                    </Border.BorderBrush>
                    <Border Name="Inner" CornerRadius="2" Padding="2" BorderThickness="1">
                        <Border.BorderBrush>
                            <SolidColorBrush Color="Blue" />
                        </Border.BorderBrush> 
                        <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="Disabled" />
                            <VisualState x:Name="ReadOnly" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                        Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FFE8EDF9" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这几乎是在互联网上可以找到的控件模板中使用visualstates的基本示例。来到鼠标悬停事件时,是不工作,背景不会改变。如果我删除内边框,它将按预期工作。

如果有人能够帮助我使用这个模板,我会非常感激。

1 个答案:

答案 0 :(得分:2)

您的问题是您将VisualStateManager.VisualStateGroups集合附加到内部Border元素,因此当您移除内部Border时,VisualStateGroups集合附加到外部再次Border,这就是它仍然奏效的原因。您需要做的就是将其移到外部Border

<Style TargetType="{x:Type TextBox}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="MinHeight" Value="20" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBoxBase}">
                <Border Name="Border" CornerRadius="2" BorderThickness="1" Margin="2" Background="White" BorderBrush="Black">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="Disabled" />
                            <VisualState x:Name="ReadOnly" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FFE8EDF9" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border Name="Inner" CornerRadius="2" Padding="2" BorderThickness="1" BorderBrush="Blue" Background="{x:Null}">
                        <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>