C# TranslateTransform移动元素超出预期
我对WPF非常陌生(对动画也完全陌生),所以我可以想象我在这里遗漏了一些东西。我正在创建一个新的布局C# TranslateTransform移动元素超出预期,c#,.net,wpf,animation,C#,.net,Wpf,Animation,我对WPF非常陌生(对动画也完全陌生),所以我可以想象我在这里遗漏了一些东西。我正在创建一个新的布局面板,它以特定的方式布置控件;这里的细节并不(或不应该)特别重要。我想做的是,当我调用Arrange时,为我正在管理的元素的移动设置动画 通常,我所做的是跟踪我用来排列每个子元素的最后一个Rect。调用ArrangeOverride时 如果启用了动画,并且元素有以前的边界Rect,我将以新的宽度和高度将其排列到该边界矩形的X和Y,然后使用两个DoubleAnimations(一个用于X,一个用于
面板
,它以特定的方式布置控件;这里的细节并不(或不应该)特别重要。我想做的是,当我调用Arrange
时,为我正在管理的元素的移动设置动画
通常,我所做的是跟踪我用来排列每个子元素的最后一个Rect
。调用ArrangeOverride
时
- 如果启用了动画,并且元素有以前的边界
,我将Rect
以新的宽度和高度将其排列到该边界矩形的X和Y,然后使用两个
s(一个用于X,一个用于Y)将其动画化到新边界的X和YDoubleAnimation
- 如果动画被禁用,或者元素没有现有的边界
,我只是Rect
将其排列到新边界
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);
}
}
}
}
公共类MyPanel:Panel
{
private Dictionary lastBounds=新字典();
受保护的覆盖尺寸测量覆盖(尺寸可用尺寸)
{
//在这里做我所有的测量,并从中删除任何内容
//已经不在面板上了。这个很好用
}
受保护的替代尺寸排列替代(尺寸最终化)
{
foreach(UIElement子元素中的子元素)
{
Rect newBounds=//获取以前计算的新边界;
TransformGroup group=child.RenderTransform作为TransformGroup;
如果(组==null)
{
组=新组();
group.Children.Add(新的TranslateTransform());
child.RenderTransform=组;
}
矩形边界;
如果(!this.lastBounds.TryGetValue(子级,超出lastBounds))
lastBounds=Rect.Empty;
如果(!lastbunds.IsEmpty&&EnableAnimation)
{
Rect tempBounds=new Rect(lastBounds.X,lastBounds.Y,newBounds.Width,newBounds.Height);
安排(临时边界);
int animationDuration=300;
DoubleAnimation xAnim=新的DoubleAnimation(newBounds.X-lastBounds.X,TimeSpan.fromMillistics(animationDuration));
DoubleAnimation yAnim=新的DoubleAnimation(newBounds.Y-lastBounds.Y,TimeSpan.fromMillistics(animationDuration));
xAnim.AccelerationRatio=yAnim.AccelerationRatio=0.2;
xAnim.减速比=yAnim.减速比=0.7;
TranslateTransform translate=group.Children[0]作为TranslateTransform;
translate.BeginAnimation(TranslateTransform.XProperty,xAnim);
translate.BeginAnimation(TranslateTransform.YProperty,yAnim);
}
其他的
{
儿童。安排(新生儿);
}
}
}
}
您似乎正在将子对象安排到其旧位置,然后应用渲染变换以使其出现在新位置。这可能是一个问题,因为您为布局引擎指定的位置现在位于父布局容器之外时,布局引擎可能有问题。您可能会更幸运地始终安排到新边界(在父元素内),然后应用“渲染平移”动画将其移回实际位置:
child.Arrange(newBounds);
int animationDuration = 300;
DoubleAnimation xAnim = new DoubleAnimation(lastBounds.X - newBounds.X, 0, TimeSpan.FromMilliseconds(animationDuration));
DoubleAnimation yAnim = new DoubleAnimation(lastBounds.Y - newBounds.Y, 0, TimeSpan.FromMilliseconds(animationDuration));
我不知道这是怎么回事……那不是把它移回到原来的位置吗?不,它把孩子的实际位置移到了新的、真实的位置(在布局方面)。应用的动画是渲染变换,以显示它在那里滑动。如果它从0,0移动到10,10,它将被安排到10,10,然后开始渲染变换,从-10,-10返回到0,0。当应用到它的新位置时,这意味着它似乎在从0,0移动到10,10。