Grow/Shrink WPF Animation
In WPF, when a user gets focus in a TextBox
, I would like some animation that would make the TextBox
becomes multiline and make its Width
bigger (while he is typing) and when the focus is lost, that the TextBox
goes back to its original size.
The size is unknown.
Also, ultimately, that TextBox
needs to be within a WPF DataGrid
.
I have never done animation before, and would like some help to get me started. Thanks.
EDIT: I have succeeded in doing the animation while having the some fixed width values (making it multiline did not work, but it is not that important). So my question now is how can I go back to my original size if that is unknown. Is there multiplier I could use on the Width
property?
Here is my code so far:
<Window.Resources>
<Storyboard x:Key="GrowStoryboard">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Width)">
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="400" KeySpline="0.54,0.27,0.38,0.69"/>
</DoubleAnimationUsingKeyFrames>
<Int32Animation Duration="0:0:0.4" From="1" To="3" Storyboard.TargetName="textBox" Storyboard.TargetProperty="(TextBox.MinLines)">
</Int32Animation>
</Storyboard>
<Storyboard x:Key="ShrinkStoryboard">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Width)">
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="200" KeySpline="0.54,0.27,0.38,0.69"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FocusManager.GotFocus" SourceName="textBox">
<BeginStoryboard x:Name="GrowStoryboard_BeginStoryboard" Storyboard="{StaticResource GrowStoryboard}"/>
</EventTrigger>
<EventTrigger RoutedEvent="FocusManager.LostFocu开发者_C百科s" SourceName="textBox">
<BeginStoryboard x:Name="ShrinkStoryboard_BeginStoryboard" Storyboard="{StaticResource ShrinkStoryboard}"/>
</EventTrigger>
</Window.Triggers>
<StackPanel>
<TextBox x:Name="textBox" Width="200" Height="20" Text="TextBox" />
<TextBox x:Name="textBox1" Width="200" Height="20" Text="TextBox" />
</StackPanel>
While there is no multiplier you could use in XAML, you could create a IValueConverter class to accomplish this. For example:
class Multiplier : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
var dblValue = 1.0;
if (value is double)
dblValue = (double)value;
else if ( !(value is string) || !double.TryParse( (string)value, out dblValue ) )
return null;
var dblParam = 1.0;
if (parameter is double)
dblParam = (double)parameter;
else if ( !(parameter is string) || !double.TryParse( (string)parameter, out dblParam ) )
return null;
return dblValue * dblParam;
}
public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
throw new NotImplementedException();
}
}
Then you can use this in the XAML to make the Textbox's width grow and shrink by a factor like so...
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Width)">
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="{Binding ElementName=textBox, Path=Width, Converter={StaticResource Multiplier}, ConverterParameter=2}" KeySpline="0.54,0.27,0.38,0.69"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Width)">
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="{Binding ElementName=textBox, Path=Width, Converter={StaticResource Multiplier}, ConverterParameter=0.5}" KeySpline="0.54,0.27,0.38,0.69"/>
</DoubleAnimationUsingKeyFrames>
精彩评论