2010-04-08 4 views
10

Ok, mi sono appena imbattuto in qualcosa che mi sta davvero prendendo alla sprovvista.Perché non è possibile animare TextBox.Text in WPF?

Stavo aiutando un collega sviluppatore con un paio di domande non correlate e nel suo progetto stava animando il testo in alcuni TextBlock. Quindi, sono tornato alla mia scrivania e ho ricreato il progetto (per rispondere alle sue domande), ma ho usato per errore TextBox anziché TextBlock. Il mio testo non si animava affatto! (Un sacco di aiuto, lo ero!)

Alla fine, ho capito che il suo xaml stava usando TextBlock e il mio stava usando TextBox. Ciò che è interessante, è che Blend non stava creando fotogrammi chiave quando stavo usando TextBox. Quindi, ho avuto modo di lavorare in Blend usando TextBlock (s) e poi modificato l'xaml a mano, convertendo il TextBlock (s) in TextBox (es). Quando ho eseguito il progetto, ho ottenuto il seguente errore:

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

Bene, sembra come se Miscela era abbastanza intelligente per sapere che ... e non generare i fotogrammi chiave nell'animazione (sarebbe solo modificare il valore direttamente sul TextBox). +1 per la miscela.

Quindi, la domanda è diventata: perché non è animabile TextBox.Text? La solita risposta è che la proprietà particolare che si sta animando non è una proprietà di dipendenza. Ma, questo non è il caso, TextBox.Text è a DependencyProperty.

Quindi, ora sono sconcertato! Perché non puoi animare TextBox.Text?


Permettetemi di includere alcuni XAML per illustrare il problema. Il seguente xaml funziona ... ma 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> 

Il seguente XAML non funziona e usa 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

Interessante ... non ne ha mai avuto bisogno, ma presumibilmente lo sarebbe sempre stato. Spero che qualcuno abbia una risposta. Mi dispiace, non posso aiutare. –

+0

Grazie per dare un'occhiata. Ammetto ... è un po 'una domanda accademica ... ma sono molto curioso di vedere una proprietà di dipendenza che non posso animare. – cplotts

risposta

28

Cercando di animare il TextBox manualmente ....

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

... rivela un messaggio di errore più utile. L'ultima riga non riesce con il seguente 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 documentazione di 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.

A quanto pare, i progettisti della biblioteca WPF deciso che animare la proprietà Text depdendency di una TextBox non è un buona idea e disabilitato esplicitamente.

Quindi, questo è il tecnico risposta al motivo per cui questa proprietà non può essere animata. Perché l'hanno disabilitato? Non ho idea ...

PS: Un rapido sguardo ai costruttori statici di TextBox, TextBoxBase e Control con riflettore rivela che Text è l'unica proprietà di dipendenza TextBox che non può essere animato.

+1

Ottima risposta! Questo mi stava facendo impazzire. È interessante notare che non vedo i metadati della proprietà impostati nel costruttore statico (utilizzando Reflector) per TextBox. In effetti, ho controllato eventuali proprietà del genere prima di pubblicare la domanda. Mi chiedo dove sono impostati i metadati della proprietà per la proprietà Text. – cplotts

+0

Il costruttore statico di 'TextBox' utilizza questo overload del costruttore' FrameworkPropertyMetadata': http://msdn.microsoft.com/en-us/library/ms557303.aspx e passa 'true' per l'argomento' isAnimationProhibited'. – Heinzi

+0

Ah, mi sono perso. Ancora, bel lavoro. – cplotts