为什么 WPF 中的 TextBox.Text 不能动画化? [英] Why isn't TextBox.Text in WPF animatable?

查看:14
本文介绍了为什么 WPF 中的 TextBox.Text 不能动画化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我刚刚遇到了一件让我措手不及的事情.

Ok, I have just run into something that is really catching me off-guard.

我正在帮助一位开发人员解决几个不相关的问题,在他的项目中,他正在将文本动画化到一些 TextBlock 中.因此,我回到办公桌前重新创建了项目(为了回答他的问题),但我不小心使用了 TextBox 而不是 TextBlock.我的文字根本没有动画!(很多帮助,我是!)

I was helping a fellow developer with a couple of unrelated questions and in his project he was animating text into some TextBlock(s). So, I went back to my desk and recreated the project (in order to answer his questions), but I accidentally used TextBox instead of TextBlock. My text wasn't animating at all! (A lot of help, I was!)

最终,我发现他的 xaml 使用的是 TextBlock,而我的 xaml 使用的是 TextBox.有趣的是,当我使用 TextBox 时,Blend 并没有创建关键帧.因此,我使用 TextBlock(s) 让它在 Blend 中工作,然后手动修改 xaml,将 TextBlock(s) 转换为 TextBox(es).运行项目时,出现以下错误:

Eventually, I figured out that his xaml was using TextBlock and mine was using TextBox. What is interesting, is that Blend wasn't creating key frames when I was using TextBox. So, I got it to work in Blend using TextBlock(s) and then modified the xaml by hand, converting the TextBlock(s) into TextBox(es). When I ran the project, I got the following error:

InvalidOperationException: '(0)' Storyboard.TargetProperty 路径包含不可动画的属性'Text'.

好吧,Blend 似乎很聪明,知道这一点......并且不会在动画中生成关键帧(它只会直接在 TextBox 上修改值).为混合 +1.

Well, it seems as if Blend was smart enough to know that ... and not generate the key frames in the animation (it would just modify the value directly on the TextBox). +1 for Blend.

所以,问题变成了:为什么 TextBox.Text 不是可动画的?通常的答案是您正在制作动画的特定属性不是 DependencyProperty.但是,事实并非如此,TextBox.Text 一个 DependencyProperty.

So, the question became: why isn't TextBox.Text animatable? The usual answer is that the particular property you are animating isn't a DependencyProperty. But, this isn't the case, TextBox.Text is a DependencyProperty.

所以,现在我很困惑!为什么不能为 TextBox.Text 设置动画?

让我包含一些 xaml 来说明问题.以下 xaml 有效...但使用 TextBlock(s).

Let me include some xaml to illustrate the problem. The following xaml works ... but uses TextBlock(s).

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="TextBoxTextQuestion.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640"
    Height="480"
>
    <Window.Resources>
        <Storyboard x:Key="animateTextStoryboard">
            <StringAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBlock.Text)" Storyboard.TargetName="textControl">
                <DiscreteStringKeyFrame KeyTime="0:0:1" Value="Goodbye"/>
            </StringAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource animateTextStoryboard}"/>
        </EventTrigger>
    </Window.Triggers>
    <Grid x:Name="LayoutRoot">
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock x:Name="textControl" Text="Hello" FontFamily="Calibri" FontSize="32"/>
            <TextBlock Text="World!" Margin="0,25,0,0" FontFamily="Calibri" FontSize="32"/>
        </StackPanel>
    </Grid>
</Window>

以下xaml不起作用并使用TextBox.Text:

The following xaml does not work and uses TextBox.Text:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="TextBoxTextQuestion.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640"
    Height="480"
>
    <Window.Resources>
        <Storyboard x:Key="animateTextStoryboard">
            <StringAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBox.Text)" Storyboard.TargetName="textControl">
                <DiscreteStringKeyFrame KeyTime="0:0:1" Value="Goodbye"/>
            </StringAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource animateTextStoryboard}"/>
        </EventTrigger>
    </Window.Triggers>
    <Grid x:Name="LayoutRoot">
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox x:Name="textControl" Text="Hello" FontFamily="Calibri" FontSize="32"/>
            <TextBox Text="World!" Margin="0,25,0,0" FontFamily="Calibri" FontSize="32"/>
        </StackPanel>
    </Grid>
</Window>

推荐答案

尝试手动为 TextBox 设置动画 ....

Trying to animate the TextBox manually ....

var timeline = new StringAnimationUsingKeyFrames();
timeline.KeyFrames.Add(new DiscreteStringKeyFrame("Goodbye", KeyTime.FromTimeSpan(new TimeSpan(0,0,1))));
textControl.BeginAnimation(TextBox.TextProperty, timeline);

...显示更有用的错误消息.最后一行失败并出现以下 ArgumentException:

...reveals a more useful error message. The last line fails with the following ArgumentException:

Text"属性在System.Windows.Controls.TextBox"类上不可设置动画,因为已在用于将属性与类关联的 UIPropertyMetadata 上设置了 IsAnimationProhibited 标志.
参数名称:dp

'Text' property is not animatable on 'System.Windows.Controls.TextBox' class because the IsAnimationProhibited flag has been set on the UIPropertyMetadata used to associate the property with the class.
Parameter name: dp

UIPropertyMetadata.IsAnimationProhibited 的文档说:

通常,Windows Presentation Foundation (WPF) 框架实现 API 中可用的默认依赖项属性可以设置动画.您可以在自己的自定义依赖属性的元数据中将此属性设置为 true 以禁用其上的动画.

In general, the default dependency properties available in the Windows Presentation Foundation (WPF) framework implementation APIs can be animated. You might set this property to true in the metadata of your own custom dependency property to disable animations on it.

显然,WPF 库的设计者认为为 TextBox 的 Text 依赖属性设置动画并不是一个好主意,并明确禁用了它.

Apparently, the designers of the WPF library decided that animating the Text depdendency property of a TextBox is not a good idea and explicitly disabled it.

所以,这就是为什么这个属性不能被动画化的技术答案.他们为什么禁用它?我不知道...

So, that's the technical answer as to why this property cannot be animated. Why did they disable it? I have no idea...

PS:使用 Reflector 快速查看 TextBoxTextBoxBaseControl 的静态构造函数会发现 Text 是唯一不能设置动画的 TextBox 依赖属性.

PS: A quick look at the static constructors of TextBox, TextBoxBase and Control with Reflector reveals that Text is the only TextBox dependency property that cannot be animated.

这篇关于为什么 WPF 中的 TextBox.Text 不能动画化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆