我对WPF很陌生(并且对动画完全不熟悉),所以我会想象这里只是我在这里失踪的东西。我正在创建一个新布局Panel
,它以特定方式放置控件;这里的细节不是(或不应该)特别重要。我想要做的就是动画化我管理的元素的移动,当我对它们调用Arrange
时。TranslateTransform移动元素超出预期
一般情况下,我所做的是跟踪最后Rect
,我曾用Arrange
每个子元素。当ArrangeOverride
叫...
- 如果动画已启用,并且有前一个边界
Rect
的元素,我把它Arrange
与新宽度和高度的边界矩形的X和Y,然后使用两个DoubleAnimation
s(一个用于X和一个用于Y)将其设置为新边界的X和Y - 如果动画被禁用或者没有现有的边界
Rect
作为元素,我只需Arrange
它到新的边界
当我禁用动画时,一切正确渲染(这是一件好事)。当我启用动画时,元素会在不正确的位置呈现。如果我调整容器的大小,他们通常会将自己重新设置回正确的位置。
编辑澄清
一般来说,出现错误时,直接关系到控制的边界的坐标。换句话说,如果控件距离开始的距离更远,那么TranslateTransform
看起来会比距离右边不太远的控件偏移更多。上/下同样如此。同样,调整大小似乎可以纠正问题(实际上,控件将自己动画化为正确的位置,这令人沮丧),但只有在整个控件集合以新大小显示时才可以。
这是类的缩写版本:
public class MyPanel : Panel
{
private Dictionary<UIElement, Rect> lastBounds = new Dictionary<UIElement, Rect>();
protected override Size MeasureOverride(Size availableSize)
{
// do all of my measurements here and delete anything from lastBounds that
// isn't on the panel any more. This works fine
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach(UIElement child in Children)
{
Rect newBounds = // get the previously calculated new bounds;
TransformGroup group= child.RenderTransform as TransformGroup;
if (group == null)
{
group = new TransformGroup();
group.Children.Add(new TranslateTransform());
child.RenderTransform = group;
}
Rect lastBounds;
if (!this.lastBounds.TryGetValue(child, out lastBounds))
lastBounds = Rect.Empty;
if (!lastBounds.IsEmpty && EnableAnimation)
{
Rect tempBounds = new Rect(lastBounds.X, lastBounds.Y, newBounds.Width, newBounds.Height);
child.Arrange(tempBounds);
int animationDuration = 300;
DoubleAnimation xAnim = new DoubleAnimation(newBounds.X - lastBounds.X, TimeSpan.FromMilliseconds(animationDuration));
DoubleAnimation yAnim = new DoubleAnimation(newBounds.Y - lastBounds.Y, TimeSpan.FromMilliseconds(animationDuration));
xAnim.AccelerationRatio = yAnim.AccelerationRatio = 0.2;
xAnim.DecelerationRatio = yAnim.DecelerationRatio = 0.7;
TranslateTransform translate = group.Children[0] as TranslateTransform;
translate.BeginAnimation(TranslateTransform.XProperty, xAnim);
translate.BeginAnimation(TranslateTransform.YProperty, yAnim);
}
else
{
child.Arrange(newBounds);
}
}
}
}
我不知道怎么会工作。 ..不会把它移回*它*的位置? – 2009-10-19 23:33:40
不,它将儿童的实际位置放置到其新的真实位置(按布局条件)。应用的动画是渲染变换以显示它在那里滑动。如果它从0,0移到10,10,它将被安排到10,10,然后开始从-10,-10回到0,0的渲染变换。当应用到新的位置时,这意味着它看起来应该从0,0移动到10,10。 – RandomEngy 2009-10-20 15:39:59
啊,这很有道理。这照顾了这个问题,谢谢! – 2009-10-20 17:05:58