为什么WPF中的TextBox.Text不可动画?

时间:2010-04-08 21:47:00

标签: wpf text animation textbox textblock

好吧,我刚遇到一些让我措手不及的事情。

我正在帮助一位开发人员提出几个不相关的问题,而在他的项目中,他正在将文本设置为一些TextBlock(s)。所以,我回到我的办公桌并重新创建项目(为了回答他的问题),但我不小心使用了 TextBox 而不是 TextBlock 。我的文字根本没有动画! (很多帮助,我是!)

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

InvalidOperationException: '(0)' Storyboard.TargetProperty path contains nonanimatable property 'Text'.

好吧,似乎Blend足够聪明,知道......并且没有在动画中生成关键帧(它只是直接修改TextBox上的值)。混合+1。

所以,问题变成了:为什么TextBox.Text不能动画化?通常的答案是您动画的特定属性不是DependencyProperty。但是,情况并非如此,TextBox.Text 是一个DependencyProperty。

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


让我包含一些xaml来说明问题。以下xaml工作...但使用TextBlock。

<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:

<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>

1 个答案:

答案 0 :(得分:28)

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

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

...显示更有用的错误消息。最后一行失败,显示以下ArgumentException

  

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

UIPropertyMetadata.IsAnimationProhibited的文档说:

  

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

显然,WPF库的设计者决定动画TextBox的Text depdendency属性不是一个好主意,并明确禁用它。

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

PS:使用Reflector快速查看TextBoxTextBoxBaseControl的静态构造函数,可以发现Text是唯一无法设置动画的TextBox依赖项属性。