4

I need to change the parent of elements. (for group/ungroup shapes) But I cant set the new position for an element if it has a rotation.

I saw this ,this , this and this pages and many other ways, but none worked correctly.

Please see my sample project and the following image:

enter image description here

The parent of Rect1 is ChildCanvas1 and The parent of Rect2 is ChildCanvas2, I want to move the Rect1 and Rect2 to the MainCanvas. (and remove the ChildCanvas and ChildCanvas2)

I don't have any problem to do that for the Rect1 because it has not any rotation. But the Rect2 has a rotation (-20 degree) and I cant set the new coordinates for it correctly.

Please see this image:

enter image description here

How to change the parent of an element after a rotation and setting new coordinates correctly?

UPDATE:

Note I need a general way (for the group/ungroup elements in a big app that each element (maybe) has TranslateTransform and SkewTransform and RotateTransform and ScaleTransform)

XAML:

<Canvas x:Name="MainCanvas">
    <Canvas x:Name="ChildCanvas1" Width="500" Height="250" Background="Bisque" Canvas.Top="54">
        <Rectangle x:Name="Rect1" Width="200" Height="100" Fill="Red" Canvas.Left="150" Canvas.Top="100"/>
    </Canvas>

    <Canvas Name="ChildCanvas2" Width="500" Height="250" Background="Bisque" Canvas.Left="516" Canvas.Top="54">
        <Rectangle Name="Rect2" Width="200" Height="100" Fill="Red" Canvas.Left="150" Canvas.Top="100">
              <Rectangle.RenderTransform>
                <TransformGroup>
                    <SkewTransform AngleX="-40"/>
                <RotateTransform Angle="-20"/>
                </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>
    <Button Name="btn1" Click="btn1_Click" Content="Move Rect1 to MainCanvas and Remove ChildCanvas1" Width="356" Height="30" Canvas.Left="59" Canvas.Top="310"/>
    <Button Name="btn2"  Click="btn2_Click" Content="Move Rect2 to MainCanvas and Remove ChildCanvas2" Width="350" Height="30" Canvas.Left="590" Canvas.Top="310"/>

C# code :

GeneralTransform transform = Rect2.TransformToVisual(MainCanvas);
Rect rect = transform.TransformBounds(new Rect(0, 0, Rect2.Width, Rect2.Height));
double ChildCanvas2Left = Canvas.GetLeft(ChildCanvas2);
double ChildCanvas2Top = Canvas.GetLeft(ChildCanvas2);
ChildCanvas2.Children.Remove(Rect2);
MainCanvas.Children.Add(Rect2);
Canvas.SetLeft(Rect2, rect.Left);
Canvas.SetTop(Rect2, rect.Top);
MainCanvas.Children.Remove(ChildCanvas2);
Community
  • 1
  • 1
Maria
  • 344
  • 8
  • 30

2 Answers2

4

You need to recalculate the Rect2 after moving the Rect2 to the MainCanvas. Like this:

Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));

The complete code:

private void btn2_Click(object sender, RoutedEventArgs e)
{       
    GeneralTransform transform = Rect2.TransformToVisual(MainCanvas);
    Rect rect = transform.TransformBounds(new Rect(0, 0, Rect2.Width, Rect2.Height));
    ChildCanvas2.Children.Remove(Rect2);
    MainCanvas.Children.Remove(ChildCanvas2);
    Canvas.SetLeft(Rect2, rect.Left);
    Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));
    MainCanvas.Children.Add(Rect2);      
}

However Rect2.TransformToVisual and transform.TransformBounds are not necessary in your case and you can do it more cleaner and easier without them and get same result. Like this:

ChildCanvas2.Children.Remove(Rect2);
MainCanvas.Children.Remove(ChildCanvas2);
Canvas.SetLeft(Rect2, Canvas.GetLeft(Rect2) + Canvas.GetLeft(ChildCanvas2));
Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));
MainCanvas.Children.Add(Rect2); 

EDIT: A general way:

ChildCanvas2.Children.Remove(Rect2);
MainCanvas.Children.Remove(ChildCanvas2);
Canvas.SetLeft(Rect2, Canvas.GetLeft(Rect2) + Canvas.GetLeft(ChildCanvas2));
Canvas.SetTop(Rect2, Canvas.GetTop(Rect2) + Canvas.GetTop(ChildCanvas2));
Canvas.SetRight(Rect2, Canvas.GetRight(Rect2) + Canvas.GetRight(ChildCanvas2));
Canvas.SetBottom(Rect2, Canvas.GetBottom(Rect2) + Canvas.GetBottom(ChildCanvas2));
MainCanvas.Children.Add(Rect2);  
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
2

I have changed RenderTransform to LayoutTransform of Rect2:

<Rectangle Name="Rect2" Width="200" Height="100" Fill="Red" Canvas.Left="150" Canvas.Top="100">
       <Rectangle.LayoutTransform>
           <RotateTransform Angle="-20"/>
       </Rectangle.LayoutTransform>
</Rectangle>

Now Rect2 looks like below:

enter image description here

When I press the second button I see this result:

enter image description here

So, Rect2 stays at the original position.

Paviel Kraskoŭski
  • 1,429
  • 9
  • 16
  • Thanks for your reply, but I need to do it using RenderTransform .(not LayoutTransform) – Maria Jun 25 '16 at 19:09