0

I have a weird problem, I register in a Grid to the event TouchMove

_outerGrid.TouchMove += _outerGrid_TouchMove;

I save the last touch point, and calculate the displacements between the last and the actual touch point.

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

Now if I try to move a UIElement accordingly, I get that the Y property updates correctly, but the X does not.

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;

I have previously created a TransformGroup with a ScaleTransform and a TranslateTransform to place the element in the right position with an animation... now if I try to move it around it doesn't work

        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);

I noticed that if I animate the Y property in the way I animate the X, also the Y starts to have the same problem. So it has something to do with animating the property and later trying to set it

Someone has any ideas of what can be causing this behaviour?

Thank you.

Marco
  • 1,454
  • 1
  • 16
  • 30
  • Your question is like me showing you the petrol cap on my car and saying that I put petrol in it, but the car doesn't run... what's wrong with it? What you need to do is to provide a [*concise, working code example that demonstrates your problem*](http://stackoverflow.com/help/mcve) and then we can test it and hopefully find a solution for you. – Sheridan Aug 07 '14 at 07:50
  • Tried to update it with some more infos – Marco Aug 07 '14 at 08:09

2 Answers2

2

This solution solves the problem:

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;

The explaination is here: http://msdn.microsoft.com/en-us/library/aa970493(v=vs.110).aspx

The DoubleAnimation is still overriding the base value. If you want the base value to become the effective value again, you must stop the animation from influencing the property, and you do it like this:

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;
Marco
  • 1,454
  • 1
  • 16
  • 30
2

If you look on the TranslateTransform Class page on MSDN, you'll see this:

enter image description here

Notice that is extends the Freezable class, which:

Defines an object that has a modifiable state and a read-only (frozen) state. Classes that derive from Freezable provide detailed change notification, can be made immutable, and can clone themselves.

So your problem was caused because the TranslateTransform is immutable (meaning that you cannot change it). Therefore, instead of attempting to change the values of the original TranslateTransform like you initially were, you need to create a new instance each time that you want to change it:

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 

Instead, create a new TranslateTransform and set that (as you discovered):

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;
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Yes, it works! But you can also apply the solution in my edited answer (which is, by the way, suggested in MSDN). Thank you! – Marco Aug 07 '14 at 09:02
  • This was not supposed to be an alternative answer. In your original answer, you wrote: *Anyway I don't know exactly why...*. I thought it would be helpful if I *explained* why. – Sheridan Aug 07 '14 at 09:41
  • Yes I understood that and now I now why :) – Marco Aug 07 '14 at 14:25