动画化以编程方式创建的 xaml 对象的翻译
Posted
技术标签:
【中文标题】动画化以编程方式创建的 xaml 对象的翻译【英文标题】:Animating the translation of a programmatically created xaml object 【发布时间】:2021-12-15 00:20:13 【问题描述】:最初我是直接在 nInput 上完成的,一切正常。 然后我尝试将其移动到克隆对象(cloneInputForAnimation),但出现此错误:
System.InvalidOperationException:名称“TextBoxAnim”不能 在“System.Windows.Controls.TextBox”的命名空间中找到
XAML:
<TextBox x:Name="nInput" MaxLength="17" PreviewTextInput="numberValidationTextBox" Grid.Column="0"
Height="80" Width="240"
Foreground="White" Background="#202020"
HorizontalAlignment="Left" BorderThickness="0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
FontSize="25">
<TextBox.RenderTransform>
<TranslateTransform x:Name="TextBoxAnim" />
</TextBox.RenderTransform>
<TextBox.Resources>
<Storyboard x:Key="myStoryboardY" x:Name="myStoryboardY">
<DoubleAnimation
Storyboard.TargetName="TextBoxAnim"
x:Name="myDoubleAnimationY"
Storyboard.TargetProperty="Y"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardX" x:Name="myStoryboardX">
<DoubleAnimation
Storyboard.TargetName="TextBoxAnim"
x:Name="myDoubleAnimationX"
Storyboard.TargetProperty="X"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardWidth" x:Name="myStoryboardWidth">
<DoubleAnimation
Storyboard.TargetName="nInput"
x:Name="myDoubleAnimationWidth"
Storyboard.TargetProperty="(TextBox.Width)"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardHeight" x:Name="myStoryboardHeight">
<DoubleAnimation
Storyboard.TargetName="nInput"
x:Name="myDoubleAnimationHeight"
Storyboard.TargetProperty="(TextBox.Height)"
Duration="0:0:0.8"
/>
</Storyboard>
</TextBox.Resources>
</TextBox>
C#:
//I clone the input box to perform the animation
TextBox cloneInputForAnimation = CloneXaml(nInput);
UserInteraction.Children.Add(cloneInputForAnimation);
//Removing text from the realInput
nInput.Text = "";
//nInput.IsEnabled = false;
//Creating a new object which is the one that will remain after the animation
TextBox targetInput = CloneXaml(cloneInputForAnimation);
targetInput.Visibility = Visibility.Hidden;
targetInput.Width = Double.NaN;
targetInput.Height = 50;
nList.Children.Add(targetInput);
//Obtaining the destination point
Point targetPosition = targetInput.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Obtaining the current point
Point currentPos = cloneInputForAnimation.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Calculating the translation to do to reach targetPosition
Vector translateToDo = targetPosition - currentPos;
//Obtaining storyboard and anim for x, y, width, height of cloneInputForAnimation (I can't use x:Name because is an element created programmatically)
Storyboard myStoryY = cloneInputForAnimation.Resources["myStoryboardY"] as Storyboard;
Storyboard myStoryX = cloneInputForAnimation.Resources["myStoryboardX"] as Storyboard;
Storyboard myStoryHeight = cloneInputForAnimation.Resources["myStoryboardHeight"] as Storyboard;
Storyboard myStoryWidth = cloneInputForAnimation.Resources["myStoryboardWidth"] as Storyboard;
DoubleAnimation myAnimY = myStoryY.Children[0] as DoubleAnimation;
DoubleAnimation myAnimX = myStoryX.Children[0] as DoubleAnimation;
DoubleAnimation myAnimHeight = myStoryHeight.Children[0] as DoubleAnimation;
DoubleAnimation myAnimWidth = myStoryWidth.Children[0] as DoubleAnimation;
myAnimY.To = translateToDo.Y;
myAnimX.To = translateToDo.X;
myAnimHeight.To = targetInput.ActualHeight;
myAnimWidth.To = targetInput.ActualWidth;
cloneInputForAnimation.BeginStoryboard(myStoryY);
cloneInputForAnimation.BeginStoryboard(myStoryX);
cloneInputForAnimation.BeginStoryboard(myStoryHeight);
cloneInputForAnimation.BeginStoryboard(myStoryWidth);
C# CloneXaml:
public static T CloneXaml<T>(T source)
string xaml = XamlWriter.Save(source);
StringReader sr = new StringReader(xaml);
XmlReader xr = XmlReader.Create(sr);
return (T)XamlReader.Load(xr);
抱歉,这是我使用 WPF 的第一步,所以代码可能会有很多问题。
【问题讨论】:
【参考方案1】:好的,正如我想象的那样,我使用了一种完全错误的方法。 这是我到达的工作版本。 XAML:
<TextBox x:Name="nInput" MaxLength="17" PreviewTextInput="numberValidationTextBox" Grid.Column="0"
Height="80" Width="240"
Foreground="White" Background="#202020"
HorizontalAlignment="Left" BorderThickness="0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
FontSize="25">
<TextBox.Resources>
<Style TargetType="x:Type Border">
<Setter Property="CornerRadius" Value="12" />
</Style>
</TextBox.Resources>
</TextBox>
C#:
Duration animDuration = new Duration(new TimeSpan(0, 0 ,0, 0,800));
//I clone the input box to perform the animation
TextBox cloneInputForAnimation = CloneXaml(nInput);
UserInteraction.Children.Add(cloneInputForAnimation);
//Removing text from the realInput
nInput.Text = "";
//nInput.IsEnabled = false;
//Creating a new object wich is the one that will remain after the animation
TextBox targetInput = CloneXaml(cloneInputForAnimation);
targetInput.Visibility = Visibility.Hidden;
targetInput.Width = double.NaN;
targetInput.Height = 50;
nList.Children.Add(targetInput);
//Obtaining the destination point
Point targetPosition = targetInput.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Obtaining the current point
Point currentPos = cloneInputForAnimation.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Calculating the translation to do to reach targetPosition
Vector translateToDo = targetPosition - currentPos;
TranslateTransform myTranslateTransform = new TranslateTransform();
cloneInputForAnimation.RenderTransform = myTranslateTransform;
DoubleAnimation myAnimX = new DoubleAnimation
Duration = animDuration,
To = translateToDo.X
;
DoubleAnimation myAnimY = new DoubleAnimation
Duration = animDuration,
To = translateToDo.Y
;
DoubleAnimation myAnimHeight = new DoubleAnimation
Duration = animDuration,
To = 50,
;
DoubleAnimation myAnimWidth = new DoubleAnimation
Duration = animDuration,
To = 50,
;
myTranslateTransform.BeginAnimation(TranslateTransform.YProperty, myAnimY);
myTranslateTransform.BeginAnimation(TranslateTransform.XProperty, myAnimX);
cloneInputForAnimation.BeginAnimation(TextBox.WidthProperty, myAnimWidth);
cloneInputForAnimation.BeginAnimation(TextBox.HeightProperty, myAnimHeight);
C# CloneXaml 未被修改
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。以上是关于动画化以编程方式创建的 xaml 对象的翻译的主要内容,如果未能解决你的问题,请参考以下文章
WPF XAML Trigger中使用动画后 动画对象冻结的处理办法
Win 10 应用开发UI Composition 札记:动画