基于xaml代码构造变换组的WPF in-code [英] Constructing WPF in-code for transform group based on the xaml code

查看:147
本文介绍了基于xaml代码构造变换组的WPF in-code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在构建我的wpf c#项目时遇到了问题。该项目假设为矩形设置动画以移动我之前设置的一定量的坐标。

例如:我的矩形位于(x = 0,y = 0)的位置。我想要点击一个按钮使其在100毫秒的间隔内移动到位置(x = 150,y = 230)。

但是,它无法运行并出现错误System.InvalidOperationException:'无法解析属性路径'RenderTransform.Children [2] .scaleY'中的所有属性引用。它突出了s.Begin(矩形);部分。



我尝试过:



这是xaml代码



I am having problem in constructing my wpf c# project. This project supposely to animate a rectangle to move a certain amount of coordinate that i have set earlier.
Ex: My rectangle is at the position (x=0,y=0). I want with a click of a button to make it move at position (x=150, y=230) in interval of 100 milliseconds.
However, it cannot run and come up with error "System.InvalidOperationException: 'Cannot resolve all property references in the property path 'RenderTransform.Children[2].scaleY'." And it's highlighting the s.Begin(rectangle); part.

What I have tried:

This is the xaml code

<Window x:Class="newStackOverflow.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:newStackOverflow"

        mc:Ignorable="d"

        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Storyboard x:Key="Storyboard1">
            <DoubleAnimationUsingKeyFrames 

                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"

                Storyboard.TargetName="rectangle">
                <EasingDoubleKeyFrame KeyTime="0:0:10" Value="300"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Canvas x:Name="canvas1" VerticalAlignment="Stretch" Background="Green">
            <Rectangle x:Name="rectangle"

                       Fill="White" Stroke="Black"

                       Height="100" Width="100"

                       Canvas.Left="10" Canvas.Top="10"

                       RenderTransformOrigin="0.5,0.5">
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Rectangle.RenderTransform>
            </Rectangle>
        </Canvas>
        <Button Content="Button"

                HorizontalAlignment="Center"

                VerticalAlignment="Center"

                Padding="10 5" Margin="10" Grid.Row="1">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
                </EventTrigger>
            </Button.Triggers>
        </Button>

    </Grid>
</Window>







这是我的代码:< br $> b $ b




And this is my in code:

public MainWindow()
       {
           InitializeComponent();


           Button button = new Button();
           button.Height = 28;
           button.Width = 58;
           button.HorizontalAlignment = HorizontalAlignment.Center;
           button.VerticalAlignment = VerticalAlignment.Center;
           button.Content = "Button";
           canvas1.Children.Add(button);

           button.Name = "button";

           this.RegisterName(button.Name, button);

           Rectangle rectangle = new Rectangle();
           rectangle.Width = 100;
           rectangle.Height = 100;
           rectangle.Fill = new SolidColorBrush(Colors.White);
           rectangle.Stroke = new SolidColorBrush(Colors.Black);
           Canvas.SetLeft(rectangle, 10);
           Canvas.SetTop(rectangle,10);
           canvas1.Children.Add(rectangle);

           rectangle.Name = "rectangle";


           TranslateTransform tt = new TranslateTransform();
           ScaleTransform st = new ScaleTransform();


           TransformGroup tg = new TransformGroup();
           tg.Children.Add(tt);
           tg.Children.Add(st);

           button.RenderTransform = tg;


           Duration duration = new Duration(TimeSpan.FromMilliseconds(10));
           DoubleAnimationUsingKeyFrames myDoubleAnim = new DoubleAnimationUsingKeyFrames();
           EasingDoubleKeyFrame myDoubleKey = new EasingDoubleKeyFrame();



           Storyboard s = new Storyboard();
           Storyboard.SetTargetName(myDoubleAnim, button.Name);
           Storyboard.SetTargetProperty(myDoubleAnim, new PropertyPath("RenderTransform.Children[1].scaleY"));

           myDoubleKey.KeyTime = KeyTime.FromPercent(1);
           myDoubleKey.Value = 300;
           myDoubleAnim.KeyFrames.Add(myDoubleKey);
           s.Children.Add(myDoubleAnim);

            s.Begin(rectangle);
           //button.Loaded += new RoutedEventHandler(buttonLoaded);


       }

推荐答案

如果存在,则无需在代码中创建Storyboard在XAML中。只需通过密钥引用XAML故事板并启动它:

You don't need to create the Storyboard in code if it exists in XAML. Simply reference the XAML Storyboard by its Key and start it:
Storyboard sb = this.FindResource("Storyboard1") as Storyboard;
sb.Begin();



如果StoryBoard没有TargetName,你可以设置一个:


If the StoryBoard does not have a TargetName, you can set one:

Storyboard sb = this.FindResource("Storyboard1") as Storyboard;
Storyboard.SetTarget(sb, rectangle);
sb.Begin();





更新



这是我发布的类似问题的答案。在这个解决方案中,他们想要一个只有XAML的解决方案 - 点击按钮并播放动画:



UPDATE

Here is an answer to a similar question that I posted. In this solution, they wanted to have a XAML only solution - click the button and play the animation:

<Window x:Class="WpfRotateImage.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"



        mc:Ignorable="d"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"



        Title="WPF CodeProject Answer - Rotate Image" Height="350" Width="525">

    <Window.Resources>
        <Storyboard x:Key="Rotate">
            <ObjectAnimationUsingKeyFrames

                Storyboard.TargetProperty="(UIElement.Visibility)"

                Storyboard.TargetName="Image1">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Visible}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Visible}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:1.01" Value="{x:Static Visibility.Hidden}"/>
            </ObjectAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames

                Storyboard.TargetProperty="(UIElement.Visibility)"

                Storyboard.TargetName="Image2">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Hidden}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:1.01" Value="{x:Static Visibility.Visible}"/>
            </ObjectAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames

                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"

                Storyboard.TargetName="Image1">
                <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
            <BeginStoryboard Storyboard="{StaticResource Rotate}"/>
        </EventTrigger>
    </Window.Triggers>

    <Grid>
        <Grid.Resources>
            <Style TargetType="Image">
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Top"/>
                <Setter Property="Margin" Value="0 10 0 0"/>
                <Setter Property="Grid.ColumnSpan" Value="8"/>
                <Setter Property="Grid.RowSpan" Value="8"/>
                <Setter Property="Width" Value="100"/>
                <Setter Property="Height" Value="100"/>
            </Style>
            <Style TargetType="Button">
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Bottom"/>
                <Setter Property="Margin" Value="0 10"/>
                <Setter Property="Padding" Value="10 5"/>
                <Setter Property="Grid.ColumnSpan" Value="8"/>
                <Setter Property="Grid.RowSpan" Value="8"/>
            </Style>
        </Grid.Resources>

        <Image x:Name="Image1" Source="https://vc.vse.cz/wp-content/uploads/2014/08/Accept-icon.png"

               RenderTransformOrigin="0.5,0.5" Visibility="Hidden">
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
        <Image x:Name="Image2" Source="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/MUTCD_R1-1.svg/2000px-MUTCD_R1-1.svg.png"/>

        <Button x:Name="button" Content="Animate"/>
    </Grid>

</Window>



Now, you want to call a storyboard against a UIElement from code-behind. So we want to change the button to raise an event and remove the Trigger for the button click event:


Now, you want to call a storyboard against a UIElement from code-behind. So we want to change the button to raise an event and remove the Trigger for the button click event:

<Window x:Class="WpfRotateImage.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"



        mc:Ignorable="d"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"



        Title="WPF CodeProject Answer - Rotate Image" Height="350" Width="525">

    <Window.Resources>
        <Storyboard x:Key="Rotate">
            <ObjectAnimationUsingKeyFrames

                Storyboard.TargetProperty="(UIElement.Visibility)"

                Storyboard.TargetName="Image1">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Visible}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Visible}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:1.01" Value="{x:Static Visibility.Hidden}"/>
            </ObjectAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames

                Storyboard.TargetProperty="(UIElement.Visibility)"

                Storyboard.TargetName="Image2">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.1" Value="{x:Static Visibility.Hidden}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:1.01" Value="{x:Static Visibility.Visible}"/>
            </ObjectAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames

                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"

                Storyboard.TargetName="Image1">
                <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>

    <Grid>
        <Grid.Resources>
            <Style TargetType="Image">
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Top"/>
                <Setter Property="Margin" Value="0 10 0 0"/>
                <Setter Property="Grid.ColumnSpan" Value="8"/>
                <Setter Property="Grid.RowSpan" Value="8"/>
                <Setter Property="Width" Value="100"/>
                <Setter Property="Height" Value="100"/>
            </Style>
            <Style TargetType="Button">
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Bottom"/>
                <Setter Property="Margin" Value="0 10"/>
                <Setter Property="Padding" Value="10 5"/>
                <Setter Property="Grid.ColumnSpan" Value="8"/>
                <Setter Property="Grid.RowSpan" Value="8"/>
            </Style>
        </Grid.Resources>

        <Image x:Name="Image1" Source="https://vc.vse.cz/wp-content/uploads/2014/08/Accept-icon.png"

               RenderTransformOrigin="0.5,0.5" Visibility="Hidden">
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
        <Image x:Name="Image2" Source="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/MUTCD_R1-1.svg/2000px-MUTCD_R1-1.svg.png"/>

        <Button x:Name="button" Content="Animate" Click="button_Click"/>
    </Grid>

</Window>



Next we need to wire up the button event:


Next we need to wire up the button event:

using System.Windows;
using System.Windows.Media.Animation;

namespace WpfRotateImage
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            var sb = FindResource("Rotate") as Storyboard;
            sb.Begin();
        }
    }
}



And bingo! The button is clicked, the code-behind is called, and the storyboard is found and started.


And bingo! The button is clicked, the code-behind is called, and the storyboard is found and started.


So is that mean i have to comment everything and make another function like i have done below?



So is that mean i have to comment everything and make another function like i have done below?

public MainWindow()
        {
            InitializeComponent();


            //Button button = new Button();
            //button.Height = 28;
            //button.Width = 58;
            //button.HorizontalAlignment = HorizontalAlignment.Center;
            //button.VerticalAlignment = VerticalAlignment.Center;
            //button.Content = "Button";
            //canvas1.Children.Add(button);

            //button.Name = "button";

            //this.RegisterName(button.Name, button);

            //Rectangle rectangle = new Rectangle();
            //rectangle.Width = 100;
            //rectangle.Height = 100;
            //rectangle.Fill = new SolidColorBrush(Colors.White);
            //rectangle.Stroke = new SolidColorBrush(Colors.Black);
            //Canvas.SetLeft(rectangle, 10);
            //Canvas.SetTop(rectangle, 10);
            //canvas1.Children.Add(rectangle);

            //rectangle.Name = "rectangle";


            //TranslateTransform tt = new TranslateTransform();
            //ScaleTransform st = new ScaleTransform();


            //TransformGroup tg = new TransformGroup();
            //tg.Children.Add(tt);
            //tg.Children.Add(st);

            //button.RenderTransform = tg;


            //Duration duration = new Duration(TimeSpan.FromMilliseconds(10));
            //DoubleAnimationUsingKeyFrames myDoubleAnim = new DoubleAnimationUsingKeyFrames();
            //EasingDoubleKeyFrame myDoubleKey = new EasingDoubleKeyFrame();



            //Storyboard s = this.FindResource("Storyboard1") as Storyboard;
            //Storyboard.SetTarget(s, rectangle);
            ////Storyboard.SetTargetProperty(s, new PropertyPath("RenderTransform.Children[1].scaleY"));

            //myDoubleKey.KeyTime = KeyTime.FromPercent(1);
            //myDoubleKey.Value = 300;
            //myDoubleAnim.KeyFrames.Add(myDoubleKey);
            //s.Children.Add(myDoubleAnim);

            ////s.Begin();
            //button.Loaded += new RoutedEventHandler(buttonLoaded);


        }

        private void buttonLoaded(object sender, RoutedEventArgs e)
        {
            Storyboard s = this.FindResource("Storyboard1") as Storyboard;
            s.Begin(this);
        }
    }
}


这篇关于基于xaml代码构造变换组的WPF in-code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆