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);
4
  • Can you show your XAML code? Commented Jun 27, 2016 at 12:26
  • @S.Akbari , Please download my sample project. Commented Jun 27, 2016 at 12:27
  • OK. Check my answer. Also please update your question and post the XAML and c# code instead of attachment to your project so that it will be reproducible to future visitors. Commented Jun 27, 2016 at 13:08
  • @S.Akbari ,OK ,Thanks. Commented Jun 27, 2016 at 13:30

2 Answers 2

4
+50

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);  
Sign up to request clarification or add additional context in comments.

Comments

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.

1 Comment

Thanks for your reply, but I need to do it using RenderTransform .(not LayoutTransform)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.