Почему TextBox.Text в WPF не поддерживает анимацию? - PullRequest
10 голосов
/ 09 апреля 2010

Хорошо, я только что столкнулся с чем-то, что действительно застало меня врасплох.

Я помогал одному разработчику с парой не связанных между собой вопросов, и в своем проекте он анимировал текст в несколько текстовых блоков. Итак, я вернулся к своему рабочему столу и пересоздал проект (чтобы ответить на его вопросы), но случайно использовал TextBox вместо TextBlock . Мой текст не был анимацией вообще! (Большая помощь, я был!)

В конце концов я понял, что его xaml использует TextBlock, а мой - TextBox. Что интересно, Blend не создавал ключевые кадры, когда я использовал TextBox. Итак, я заставил его работать в Blend с использованием TextBlock (ов), а затем вручную изменил xaml, преобразовав TextBlock (s) в TextBox (ы). Когда я запустил проект, я получил следующую ошибку:

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>

1 Ответ

28 голосов
/ 09 апреля 2010

Попытка анимировать TextBox вручную ....

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

... показывает более полезное сообщение об ошибке. Последняя строка завершается с ошибкой ArgumentException:

Свойство «Текст» не может быть анимировано в классе «System.Windows.Controls.TextBox», поскольку в UIPropertyMetadata был установлен флаг IsAnimationProjected, используемый для связывания свойства с классом.
Имя параметра: дп

Документация UIPropertyMetadata.IsAnimationProjected гласит:

Как правило, свойства зависимостей по умолчанию, доступные в API реализации платформы Windows Presentation Foundation (WPF), можно анимировать. Вы можете установить для этого свойства значение true в метаданных своего собственного пользовательского свойства зависимостей, чтобы отключить анимацию для него.

Очевидно, разработчики библиотеки WPF решили, что анимировать свойство depdendency Text TextBox не является хорошей идеей, и явно отключили его.

Итак, это технический ответ о том, почему это свойство нельзя анимировать. Почему они отключили это? Понятия не имею ...

PS: Быстрый просмотр статических конструкторов TextBox, TextBoxBase и Control с помощью Reflector показывает, что Text - единственное свойство зависимостей TextBox, которое нельзя анимировать.

...