WPF:TranslateTransform X属性未更新

时间:2014-08-07 07:34:27

标签: c# wpf transformation uielement

我有一个奇怪的问题,我在Grid中注册事件TouchMove

_outerGrid.TouchMove += _outerGrid_TouchMove;

我保存最后一个触摸点,并计算最后一个触摸点和实际触摸点之间的位移。

double dx = actualPoint.X - _lastMovePoint.X;
double dy = actualPoint.Y - _lastMovePoint.Y;

现在,如果我尝试相应地移动UIElement,我会得到Y属性正确更新,但X没有。

TransformGroup tg = element.RenderTransform as TransformGroup;

TranslateTransform t = tg.Children[1] as TranslateTransform;
t.X += dx; //Remains unchanged after the sum, and dx != 0
t.Y += dy;

我之前创建了一个带有ScaleTransform和TranslateTransform的TransformGroup,用动画将元素放在正确的位置......现在如果我试图移动它就不起作用

        double startPointX = -100;
        double accelRatio = 0.5;
        double decelRatio = 0.5;

        element.RenderTransformOrigin = new Point(0.5, 0.5);

        TransformGroup tg = tg = new TransformGroup();
        TranslateTransform t = new TranslateTransform();
        ScaleTransform s = new ScaleTransform();

        tg.Children.Add(s);
        tg.Children.Add(t);
        element.RenderTransform = tg;

        DoubleAnimation xAnim = new DoubleAnimation();
        xAnim.From = displX - startPointX;
        xAnim.To = displX;
        xAnim.Duration = TimeSpan.FromMilliseconds(dur);
        xAnim.BeginTime = TimeSpan.FromMilliseconds(delay);
        xAnim.AccelerationRatio = accelRatio;
        xAnim.DecelerationRatio = decelRatio;

        DoubleAnimation sAnim = new DoubleAnimation();
        sAnim.From = 0;
        sAnim.To = 1;
        sAnim.Duration = TimeSpan.FromMilliseconds(dur);
        sAnim.BeginTime = TimeSpan.FromMilliseconds(delay);

        DoubleAnimation oAnim = new DoubleAnimation();
        oAnim.From = 0;
        oAnim.To = 1;
        oAnim.Duration = TimeSpan.FromMilliseconds(dur);
        oAnim.BeginTime = TimeSpan.FromMilliseconds(delay);

        s.BeginAnimation(ScaleTransform.ScaleXProperty, sAnim);
        s.BeginAnimation(ScaleTransform.ScaleYProperty, sAnim);
        t.BeginAnimation(TranslateTransform.XProperty, xAnim);
        t.Y = displY;

        element.BeginAnimation(OpacityProperty, oAnim);

我注意到如果我以动画X的方式设置Y属性的动画,Y也开始出现同样的问题。所以它与动画属性有关,后来试图设置它

有人对可能导致此行为的原因有任何想法吗?

谢谢。

2 个答案:

答案 0 :(得分:2)

此解决方案解决了这个问题:

TransformGroup tg = element.RenderTransform as TransformGroup;

TranslateTransform t = new TranslateTransform();
t.X = (tg.Children[1] as TranslateTransform).X + dx;
t.Y = (tg.Children[1] as TranslateTransform).Y + dy;

tg.Children[1] = t;

解释在这里:http://msdn.microsoft.com/en-us/library/aa970493(v=vs.110).aspx

DoubleAnimation仍然覆盖基值。如果希望基值再次成为有效值,则必须停止影响属性,并且执行此操作:

TransformGroup tg = element.RenderTransform as TransformGroup;

TranslateTransform t = tg.Children[1] as TranslateTransform;
double tx = t.X;
double ty = t.Y;
t.BeginAnimation(TranslateTransform.XProperty, null);
t.BeginAnimation(TranslateTransform.YProperty, null);
t.X = tx + dx;
t.Y = ty + dy;

答案 1 :(得分:1)

如果您查看MSDN上的TranslateTransform Class页面,您会看到:

enter image description here

请注意,它扩展了Freezable class,其中:

  

定义具有可修改状态和只读(冻结)状态的对象。从Freezable派生的类提供详细的更改通知,可以变为不可变的,并且可以自我克隆。

所以你的问题是因为TranslateTransform是不可变的(这意味着你无法改变它)。因此,您不必像最初那样尝试更改原始TranslateTransform的值,而是每次要更改它时都需要创建一个新实例

TransformGroup tg = element.RenderTransform as TransformGroup;    
TranslateTransform t = tg.Children[1] as TranslateTransform;
t.X += dx; // Remains unchanged because TranslateTransform is immutable 
t.Y += dy; // Remains unchanged because TranslateTransform is immutable 

相反,创建一个新的TranslateTransform并设置(如您所发现的):

TransformGroup tg = element.RenderTransform as TransformGroup;    
TranslateTransform t = new TranslateTransform(); // Use new TranslateTransform here
t.X = (tg.Children[1] as TranslateTransform).X + dx;
t.Y = (tg.Children[1] as TranslateTransform).Y + dy;    
tg.Children[1] = t;