10

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

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

最终,我发现他的 xaml 使用的是 TextBlock,而我的使用的是 TextBox。有趣的是,当我使用 TextBox 时,Blend 并没有创建关键帧。因此,我使用 TextBlock(s) 让它在 Blend 中工作,然后手动修改 xaml,将 TextBlock(s) 转换为 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(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:

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

1 回答 1

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 库的设计者认为Text为 TextBox 的依赖属性设置动画不是一个好主意,并明确禁用了它。

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

PS:快速浏览一下TextBox,TextBoxBaseControlReflector 的静态构造函数,可以发现这Text是唯一一个不能动画的 TextBox 依赖属性。

于 2010-04-08T22:25:25.937 回答