首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在WPF中设置TextBox.Foreground动画

在WPF中设置TextBox.Foreground动画
EN

Stack Overflow用户
提问于 2013-08-25 05:59:41
回答 3查看 15.9K关注 0票数 7

有没有办法让TextBox.ForegroundProperty动画化?

代码语言:javascript
运行
复制
<Color x:Key="NormalColor">#FF666666</Color>
<SolidColorBrush x:Key="NormalBrush" Color="{StaticResource NormalColor}" />

<Color x:Key="MouseOverColor">#FF666666</Color>
<SolidColorBrush x:Key="MouseOverBrush" Color="{StaticResource MouseOverColor}" />

<ControlTemplate x:Key="RegularTextBoxTemplate" TargetType="{x:Type TextBox}">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.1"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <!-- storyboard to animating foreground here... -->
                    </Storyboard>
                </VisualState>
            </VisualStateGroup >
        </VisualStateManager>
        <ScrollViewer x:Name="PART_ContentHost" 
                      BorderThickness="0"
                      IsTabStop="False"
                      Background="{x:Null}"/>
    </Grid>
</ControlTemplate>

<Style x:Key="RegularTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground" Value="{StaticResource NormalBrush}"/>
    <Setter Property="Template" Value="{StaticResource RegularTextBoxTemplate}"/>
</Style>

我尝试过的故事板是:

代码语言:javascript
运行
复制
<ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_ContentHost"
                  Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_ContentHost"
              Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_ContentHost"
          Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
                  Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
              Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
              Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

<ColorAnimationUsingKeyFrames
          Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

它们都不起作用。有什么想法吗?这有可能吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-25 10:06:37

好吧,感谢所有那些试图帮助我的人,我找到了我的答案。似乎当我们将TextBox.Foreground属性设置为资源时,情节提要不能对其进行动画处理。因此,样式应该是这样的:

代码语言:javascript
运行
复制
<Style x:Key="RegularTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground">
        <Setter.Value>
            <SolidColorBrush Color="{DynamicResource NormalColor}"/>
        </Setter.Value>
    </Setter>
    <Setter Property="Template" Value="{StaticResource RegularTextBoxTemplate}"/>
</Style>

这是我唯一的问题。但有一点需要记住。当我们想要在故事板中定位一个模板化的父级时,没有必要绑定到它。我们只需要把它放在一边:

代码语言:javascript
运行
复制
<!-- It's not necessary to set Storyboard.TargetName in storyboard -->
<!-- It will automatically target the TemplatedParent -->
<ColorAnimationUsingKeyFrames
              Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

这对我很有效。

Here就是一个有效的例子。

票数 11
EN

Stack Overflow用户

发布于 2013-08-25 06:07:45

这比我想象的更有问题。这是我最初的答案:

这绝对是可能的--这就是ColorAnimationXXX类的用途。

您的代码与代码示例here非常相似,后者使用ColorAnimation为颜色提供动画效果。示例中的属性采用笔刷(就像TextBox.Foreground一样),它是在XAML中定义的,并为其指定了一个名称,以便动画可以轻松地引用它。

因此,在您的示例中,相关代码为:

代码语言:javascript
运行
复制
<VisualState Name="...">
   <Storyboard>
      <ColorAnimation To="Green" 
                      Storyboard.TargetName="tbBrush" 
                      Storyboard.TargetProperty="Color"/>
    </Storyboard>
</VisualState>

和:

代码语言:javascript
运行
复制
<TextBox.Foreground>
  <SolidColorBrush x:Name="tbBrush" Color="#FF666666"/>
</TextBox.Foreground>

从理论上讲,这一切都很好,直到我意识到它在一种风格中不起作用。而样式中的网格的Background属性很容易设置动画,如下所示:

代码语言:javascript
运行
复制
Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)"

要找到一个对文本前景有影响的属性来进行动画效果明显要困难得多。最初我尝试了TextElement.Foreground,它看起来很直观,我能够在网格和ScrollViewer级别设置这个属性,我希望它能对下面的所有子对象产生影响-包括在包含TextBox文本的底层的任何对象。我的假设是,TextBox内容将在内部设置为一个TextBlock,它将遵循在其上设置的Foreground属性的值。似乎我的假设是错误的,PART_ContentHost ScrollViewer的内容被TextBox中的控制逻辑设置为一个较低级别的对象,该对象不遵守对象树中顶层TextBox与其自身之间的任何前台依赖属性。

然后,问题是如何在所设置样式的TextBox的样式中设置TextBox的前景属性。为了进行测试,我尝试使用TwoWay TemplatedParent绑定来设置它。我想我将PropertyPath设置为SolidColorBrush的颜色是正确的,但它仍然不起作用,因为颜色属性在那时显然是不可变的。我相信这个问题是有文档记录的here

除了不起作用之外,在内部设置前景属性似乎并不正确,因为外部消费者希望控制该属性的价值。因此,考虑到TextBox的前景不会遵从样式中的任何内容,我得出的结论是,最好使用TextBox样式中的嵌套TextBox来实现该功能。外部样式包含状态管理器和大部分布局,内部TextBox具有自己的样式和控件模板,该模板仅用于显示文本位。外部样式能够设置内部样式的前景属性,内部样式将遵循该属性,更重要的是,外部样式可以在状态管理器中设置此值。

代码语言:javascript
运行
复制
<ControlTemplate x:Key="RegularTextBoxTemplate" TargetType="{x:Type TextBox}"> 
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.1"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation To="HotPink"
                            Storyboard.TargetName="InternalTextBox"
                            Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <TextBox Foreground="Black" Text="{TemplateBinding Text}" x:Name="InternalTextBox">
            <TextBox.Style>
                <Style TargetType="{x:Type TextBox}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type TextBox}">
                                <Grid Background="{x:Null}">
                                    <ScrollViewer x:Name="PART_ContentHost"
                                        BorderThickness="0"
                                        IsTabStop="False"
                                        Background="{x:Null}" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TextBox.Style>
        </TextBox>
    </Grid>
</ControlTemplate>

<Style x:Key="RegularTextBox" TargetType="{x:Type TextBox}">
    <Setter Property="Template" Value="{StaticResource RegularTextBoxTemplate}"/>
</Style>

我很有兴趣听到其他人对这种方法的评论,以及这种方法是否存在我没有考虑到的问题。根据我在解决问题和侦听结果应用程序的尝试,这是目前我所能看到的最简单的解决方案。

票数 9
EN

Stack Overflow用户

发布于 2013-08-25 09:45:06

您可以将Storyboard.Target绑定到TemplatedParent:

代码语言:javascript
运行
复制
<ColorAnimationUsingKeyFrames
        Storyboard.Target="{Binding RelativeSource={RelativeSource TemplatedParent}}"
        Storyboard.TargetProperty="(TextBox.Foreground).(SolidColorBrush.Color)">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverColor}" />
</ColorAnimationUsingKeyFrames>

不幸的是,只有当正常的前景笔刷在样式中设置为而不是,并且直接在TextBox元素上设置时,我才能让它工作:

代码语言:javascript
运行
复制
<TextBox Foreground="{StaticResource NormalBrush}" Style="{StaticResource RegularTextBox}" />

如果在样式中设置了它,则触发MouseOver状态抛出“无法在不可变对象实例上设置'(0).(1)‘的动画。”编辑:如果您在初始化TextBox前景之后再次设置它,也会发生这种情况。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18423547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档