如何在 C# WPF 中为自定义形状对象设置动画
How to animate a custom shape object in c# WPF
我对 c# 和 WPF 比较陌生,也许这就是为什么我找不到(可能非常明显的)问题答案的原因。我一直在尝试和谷歌搜索但没有成功。
我有一个自定义形状 class,在一个 GeometryGroup 中有 returns 3 个 RectangleGeometries。 3个对应的矩形可以按预期显示在MainWindow中的Canvas中。我现在想分别为每个矩形制作动画,比如将第一个放在 canvas 的底部,旋转第二个并为第三个的宽度设置动画。
我自己的研究表明关键是依赖属性。所以我注册了他们,但我无法让他们对矩形进行任何更改。
我最好在后台代码中完成所有这些工作。只有 Canvas
已添加到 XAML。可以吗?这是一些可以使用的代码。
提前致谢
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Test1
{
public partial class MainWindow : Window
{
CustomShape customShape = new CustomShape();
public MainWindow()
{
InitializeComponent();
customShape.Fill = Brushes.Blue;
cnvMain.Children.Add(customShape);
}
}
class CustomShape : Shape
{
private Rect rect1, rect2, rect3;
private RectangleGeometry rg1, rg2, rg3;
private GeometryGroup allRectangleGeometries = new GeometryGroup();
//Constructor
public CustomShape()
{
makeCustomShape();
}
private void makeCustomShape()
{
rect1 = new Rect(50, 20, 100, 50);
rg1 = new RectangleGeometry(rect1);
allRectangleGeometries.Children.Add(rg1);
rect2 = new Rect(200, 20, 60, 20);
rg2 = new RectangleGeometry(rect2);
allRectangleGeometries.Children.Add(rg2);
rect3 = new Rect(300, 20, 200, 80);
rg3 = new RectangleGeometry(rect3);
allRectangleGeometries.Children.Add(rg3);
}
protected override Geometry DefiningGeometry
{
get
{
return allRectangleGeometries;
}
}
}
}
看来我自己找到了答案。
我实现了 3 个依赖属性和一个每次 属性 更改时执行的回调方法。
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Test1
{
public partial class MainWindow : Window
{
CustomShape customShape = new CustomShape();
public MainWindow()
{
InitializeComponent();
customShape.Fill = Brushes.Blue;
cnvMain.Children.Add(customShape);
}
private void ButtonAnimate_Clicked(object sender, RoutedEventArgs e)
{
DoubleAnimation rec1Animation = new DoubleAnimation(500, TimeSpan.FromSeconds(1));
customShape.BeginAnimation(CustomShape.Rec1YProperty, rec1Animation);
DoubleAnimation rec2Animation = new DoubleAnimation(360, TimeSpan.FromSeconds(1));
customShape.BeginAnimation(CustomShape.Rec2RotateProperty, rec2Animation);
DoubleAnimation rec3Animation = new DoubleAnimation(400, TimeSpan.FromSeconds(1));
customShape.BeginAnimation(CustomShape.Rec3WidthProperty, rec3Animation);
}
}
class CustomShape : Shape
{
private Rect rect1, rect2, rect3;
private RectangleGeometry rg1, rg2, rg3;
private GeometryGroup allRectangleGeometries = new GeometryGroup();
public double Rec1Y
{
get { return (double)GetValue(Rec1YProperty); }
set { SetValue(Rec1YProperty, value); }
}
public static readonly DependencyProperty Rec1YProperty =
DependencyProperty.Register("Rec1Y", typeof(double), typeof(CustomShape), new PropertyMetadata(20d, new PropertyChangedCallback(OnAnyPropertyChanged)));
public double Rec2Rotate
{
get { return (double)GetValue(Rec2RotateProperty); }
set { SetValue(Rec2RotateProperty, value); }
}
public static readonly DependencyProperty Rec2RotateProperty =
DependencyProperty.Register("Rec2Rotate", typeof(double), typeof(CustomShape), new PropertyMetadata(0d, new PropertyChangedCallback(OnAnyPropertyChanged)));
public double Rec3Width
{
get { return (double)GetValue(Rec3WidthProperty); }
set { SetValue(Rec3WidthProperty, value); }
}
public static readonly DependencyProperty Rec3WidthProperty =
DependencyProperty.Register("Rec3Width", typeof(double), typeof(CustomShape), new PropertyMetadata(200d, new PropertyChangedCallback(OnAnyPropertyChanged)));
//Constructor
public CustomShape()
{
makeCustomShape();
}
private void makeCustomShape()
{
rect1 = new Rect(50, Rec1Y, 100, 50);
rg1 = new RectangleGeometry(rect1);
allRectangleGeometries.Children.Add(rg1);
rect2 = new Rect(200, 20, 60, 20);
rg2 = new RectangleGeometry(rect2);
rg2.Transform = new RotateTransform(Rec2Rotate, 230, 30);
allRectangleGeometries.Children.Add(rg2);
rect3 = new Rect(300, 20, Rec3Width, 80);
rg3 = new RectangleGeometry(rect3);
allRectangleGeometries.Children.Add(rg3);
}
private static void OnAnyPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
CustomShape customShape = source as CustomShape;
customShape.allRectangleGeometries.Children.Clear();
customShape.makeCustomShape();
}
protected override Geometry DefiningGeometry
{
get
{
return allRectangleGeometries;
}
}
}
}
我对 c# 和 WPF 比较陌生,也许这就是为什么我找不到(可能非常明显的)问题答案的原因。我一直在尝试和谷歌搜索但没有成功。
我有一个自定义形状 class,在一个 GeometryGroup 中有 returns 3 个 RectangleGeometries。 3个对应的矩形可以按预期显示在MainWindow中的Canvas中。我现在想分别为每个矩形制作动画,比如将第一个放在 canvas 的底部,旋转第二个并为第三个的宽度设置动画。
我自己的研究表明关键是依赖属性。所以我注册了他们,但我无法让他们对矩形进行任何更改。
我最好在后台代码中完成所有这些工作。只有 Canvas 已添加到 XAML。可以吗?这是一些可以使用的代码。
提前致谢
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Test1
{
public partial class MainWindow : Window
{
CustomShape customShape = new CustomShape();
public MainWindow()
{
InitializeComponent();
customShape.Fill = Brushes.Blue;
cnvMain.Children.Add(customShape);
}
}
class CustomShape : Shape
{
private Rect rect1, rect2, rect3;
private RectangleGeometry rg1, rg2, rg3;
private GeometryGroup allRectangleGeometries = new GeometryGroup();
//Constructor
public CustomShape()
{
makeCustomShape();
}
private void makeCustomShape()
{
rect1 = new Rect(50, 20, 100, 50);
rg1 = new RectangleGeometry(rect1);
allRectangleGeometries.Children.Add(rg1);
rect2 = new Rect(200, 20, 60, 20);
rg2 = new RectangleGeometry(rect2);
allRectangleGeometries.Children.Add(rg2);
rect3 = new Rect(300, 20, 200, 80);
rg3 = new RectangleGeometry(rect3);
allRectangleGeometries.Children.Add(rg3);
}
protected override Geometry DefiningGeometry
{
get
{
return allRectangleGeometries;
}
}
}
}
看来我自己找到了答案。 我实现了 3 个依赖属性和一个每次 属性 更改时执行的回调方法。
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Test1
{
public partial class MainWindow : Window
{
CustomShape customShape = new CustomShape();
public MainWindow()
{
InitializeComponent();
customShape.Fill = Brushes.Blue;
cnvMain.Children.Add(customShape);
}
private void ButtonAnimate_Clicked(object sender, RoutedEventArgs e)
{
DoubleAnimation rec1Animation = new DoubleAnimation(500, TimeSpan.FromSeconds(1));
customShape.BeginAnimation(CustomShape.Rec1YProperty, rec1Animation);
DoubleAnimation rec2Animation = new DoubleAnimation(360, TimeSpan.FromSeconds(1));
customShape.BeginAnimation(CustomShape.Rec2RotateProperty, rec2Animation);
DoubleAnimation rec3Animation = new DoubleAnimation(400, TimeSpan.FromSeconds(1));
customShape.BeginAnimation(CustomShape.Rec3WidthProperty, rec3Animation);
}
}
class CustomShape : Shape
{
private Rect rect1, rect2, rect3;
private RectangleGeometry rg1, rg2, rg3;
private GeometryGroup allRectangleGeometries = new GeometryGroup();
public double Rec1Y
{
get { return (double)GetValue(Rec1YProperty); }
set { SetValue(Rec1YProperty, value); }
}
public static readonly DependencyProperty Rec1YProperty =
DependencyProperty.Register("Rec1Y", typeof(double), typeof(CustomShape), new PropertyMetadata(20d, new PropertyChangedCallback(OnAnyPropertyChanged)));
public double Rec2Rotate
{
get { return (double)GetValue(Rec2RotateProperty); }
set { SetValue(Rec2RotateProperty, value); }
}
public static readonly DependencyProperty Rec2RotateProperty =
DependencyProperty.Register("Rec2Rotate", typeof(double), typeof(CustomShape), new PropertyMetadata(0d, new PropertyChangedCallback(OnAnyPropertyChanged)));
public double Rec3Width
{
get { return (double)GetValue(Rec3WidthProperty); }
set { SetValue(Rec3WidthProperty, value); }
}
public static readonly DependencyProperty Rec3WidthProperty =
DependencyProperty.Register("Rec3Width", typeof(double), typeof(CustomShape), new PropertyMetadata(200d, new PropertyChangedCallback(OnAnyPropertyChanged)));
//Constructor
public CustomShape()
{
makeCustomShape();
}
private void makeCustomShape()
{
rect1 = new Rect(50, Rec1Y, 100, 50);
rg1 = new RectangleGeometry(rect1);
allRectangleGeometries.Children.Add(rg1);
rect2 = new Rect(200, 20, 60, 20);
rg2 = new RectangleGeometry(rect2);
rg2.Transform = new RotateTransform(Rec2Rotate, 230, 30);
allRectangleGeometries.Children.Add(rg2);
rect3 = new Rect(300, 20, Rec3Width, 80);
rg3 = new RectangleGeometry(rect3);
allRectangleGeometries.Children.Add(rg3);
}
private static void OnAnyPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
CustomShape customShape = source as CustomShape;
customShape.allRectangleGeometries.Children.Clear();
customShape.makeCustomShape();
}
protected override Geometry DefiningGeometry
{
get
{
return allRectangleGeometries;
}
}
}
}