简体   繁体   English

动画以编程方式创建的 xaml 对象的翻译

[英]Animating the translation of a programmatically created xaml object

Initially I did it directly on nInput and everything worked.最初我是直接在 nInput 上做的,一切正常。 Then I tried to move it to a cloned object (cloneInputForAnimation) but I get this error:然后我尝试将它移动到一个克隆对象(cloneInputForAnimation),但我收到此错误:

System.InvalidOperationException: The name 'TextBoxAnim' could not be found in the namespace of 'System.Windows.Controls.TextBox' System.InvalidOperationException: 在“System.Windows.Controls.TextBox”的命名空间中找不到名称“TextBoxAnim”

XAML: 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#: 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: 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);
        }

Sorry but these are my first steps with WPF so the code will probably have a lot of problems.抱歉,这些是我使用 WPF 的第一步,因此代码可能会有很多问题。

Okay, as I imagined I was using a completely wrong approach.好吧,正如我想象的那样,我使用了一种完全错误的方法。 This is the working version I have arrived at.这是我到达的工作版本。 XAML: 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#: 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 has not been modified C# CloneXaml 未修改

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM