2010-04-08 20 views
10

Ok, acabo de encontrarme con algo que realmente me está tomando por sorpresa.¿Por qué no TextBox.Text en WPF puede ser animado?

Estaba ayudando a un desarrollador compañero con un par de preguntas no relacionadas y en su proyecto estaba animando texto en algunos TextBlock (s). Entonces, volví a mi escritorio y recreé el proyecto (para responder sus preguntas), pero accidentalmente usé TextBox en lugar de TextBlock. ¡Mi texto no estaba animando en absoluto! (¡Mucha ayuda, lo fui!)

Eventualmente, descubrí que su xaml estaba usando TextBlock y el mío estaba usando TextBox. Lo que es interesante, es que Blend no estaba creando fotogramas clave cuando estaba usando TextBox. Entonces, conseguí que funcione en Blend usando TextBlock (s) y luego modifiqué el xaml a mano, convirtiendo el TextBlock (s) en TextBox (es). Cuando me encontré con el proyecto, tengo el siguiente error:

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

Pues bien, parece como si la mezcla fue lo suficientemente inteligente para saber que ... y no generar los fotogramas clave en la animación (que sería sólo modificar el valor directamente en el TextBox). +1 para Mezcla.

Entonces, la pregunta fue: ¿por qué TextBox.Text no es animable? La respuesta habitual es que la propiedad particular que está animando no es DependencyProperty. Pero, este no es el caso, TextBox.Text es a DependencyProperty.

¡Así que ahora estoy desconcertado! ¿Por qué no puedes animar TextBox.Text?


Let Me incluyo algunos xaml para ilustrar el problema. El siguiente xaml funciona ... pero usa 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> 

El siguiente XAML no funciona y utiliza 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> 
+0

Interesante ... nunca tuve la necesidad de esto, pero siempre supuse que sería. Espero que alguien tenga una respuesta. Lo siento, no puedo ayudar. –

+0

Gracias por echar un vistazo. Lo admito ... es una pequeña pregunta académica ... pero tengo mucha curiosidad de ver una DependencyProperty que no puedo animar. – cplotts

Respuesta

28

Tratando de animar el cuadro de texto de forma manual ....

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

... revela una mensaje de error más útil. La última línea de falla con el siguiente ArgumentException:

'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

La documentación de UIPropertyMetadata.IsAnimationProhibited dice:

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.

Al parecer, los diseñadores de la biblioteca WPF decidió que la animación de la propiedad Text depdendency de un cuadro de texto no es una buena idea y explícitamente inhabilitada.

Por lo tanto, esa es la técnica respuesta de por qué esta propiedad no se puede animar. ¿Por qué lo deshabilitaron? No tengo ni idea ...

PD: Un rápido vistazo a los constructores estáticos de TextBox, TextBoxBase y Control con reflector revela que Text es la única propiedad de dependencia cuadro de texto que no puede ser animado.

+1

¡Gran respuesta! Esto me estaba volviendo loco. Curiosamente, no veo los metadatos de propiedades establecidos en el constructor estático (utilizando Reflector) para TextBox. De hecho, revisé todas las propiedades antes de publicar la pregunta. Me pregunto dónde se establecen los metadatos de la propiedad para la propiedad Text. – cplotts

+0

El constructor estático de 'TextBox' usa esta sobrecarga del constructor' FrameworkPropertyMetadata': http://msdn.microsoft.com/en-us/library/ms557303.aspx y pasa 'true' para el argumento' isAnimationProhibited'. – Heinzi

+0

Ah, me lo perdí. De nuevo, buen trabajo. – cplotts

Cuestiones relacionadas