【发布时间】:2017-01-20 16:11:15
【问题描述】:
请考虑以下说明我的问题的简化示例:
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="500" Height="500"
Title="Click anywhere to animate the movement of the blue thingy...">
<Canvas
x:Name="canvas"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="AntiqueWhite"
MouseDown="canvas_MouseDown" />
</Window>
MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.canvas.Children.Add(new Thingy());
}
private void canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
var thingy = (Thingy)this.canvas.Children[0];
var from = new Point(0.0, 0.0);
var to = new Point(
canvas.ActualWidth - thingy.ActualWidth,
canvas.ActualHeight - thingy.ActualHeight
);
var locAnim = new PointAnimation(
from,
to,
new Duration(TimeSpan.FromSeconds(5))
);
locAnim.Completed += (s, a) =>
{
// Only at this line does the thingy move to the
// correct position...
thingy.Location = to;
};
thingy.Location = from;
thingy.BeginAnimation(Thingy.LocationProperty, locAnim);
}
}
}
Thingy.xaml
<UserControl x:Class="WpfApplication1.Thingy"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="50" Height="50" Background="Blue" />
Thingy.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfApplication1
{
public partial class Thingy : UserControl
{
public static DependencyProperty LocationProperty =
DependencyProperty.Register(
"Location",
typeof(Point),
typeof(Thingy)
);
public Thingy()
{
InitializeComponent();
Canvas.SetLeft(this, 0.0);
Canvas.SetTop(this, 0.0);
var xBind = new Binding();
xBind.Source = this;
xBind.Path = new PropertyPath(Canvas.LeftProperty);
xBind.Mode = BindingMode.TwoWay;
var yBind = new Binding();
yBind.Source = this;
yBind.Path = new PropertyPath(Canvas.TopProperty);
yBind.Mode = BindingMode.TwoWay;
var locBind = new MultiBinding();
locBind.Converter = new PointConverter();
locBind.Mode = BindingMode.TwoWay;
locBind.Bindings.Add(xBind);
locBind.Bindings.Add(yBind);
BindingOperations.SetBinding(
this,
Thingy.LocationProperty,
locBind
);
}
public Point Location
{
get
{
return (Point)this.GetValue(LocationProperty);
}
set
{
this.SetValue(LocationProperty, value);
}
}
}
}
PointConverter.cs
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace WpfApplication1
{
public class PointConverter : IMultiValueConverter
{
public object Convert(object[] v, Type t, object p, CultureInfo c)
{
return new Point((double)v[0], (double)v[1]);
}
public object[] ConvertBack(object v, Type[] t, object p, CultureInfo c)
{
return new object[] { ((Point)v).X, ((Point)v).Y };
}
}
}
这里的目标是:
- 使用
LocationProperty操作和访问Canvas.LeftProperty和Canvas.TopProperty值。 - Animate 使用
PointAnimation类表示LocationProperty。
目标 #1 似乎工作正常,只是在尝试为 LocationProperty 设置动画时,它的行为才没有达到预期。
“预期”是指Thingy 的实例应该随着动画的进行而移动。
我可以使用DoubleAnimation 类的两个实例来完成此操作。
如果问题是Point是一个值类型,那么我怀疑我可以定义我自己的Point类型和我自己的AnimationTimeline。这不是我想做的。这是一个更大项目的一部分,LocationProperty 将用于其他事情。
老实说,最重要的是,在我看来这应该是可行的,你能告诉我吗:
- 为什么不呢?
- 是否有定义的问题解决方案?
我还要提到,我的目标是 .Net Framework 4.5 用于这个项目。
谢谢。
【问题讨论】:
-
不确定这是否有帮助,但您是否尝试过将 TranslateTransform 附加到 Thingy 并绑定/动画转换而不是 Canvas.Left 和 Canvas.Top?至少它会表现得更好。
-
当您说“我可以使用 DoubleAnimation 类的两个实例来完成此任务”。你什么意思?在这种情况下,您要为哪些属性设置动画?
-
@PeterMoore 感谢 TranslateTransform 的想法,我一定会调查的。为了回答你的问题,我在 Canvas.Left/Top 上使用了 DoubleAnimations。
-
明白了,有道理。请参阅我的更新答案,了解为什么您的原始方法不起作用。