Reputation: 364
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:
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:
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);
Upvotes: 4
Views: 1420
Reputation: 39946
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);
Upvotes: 4
Reputation: 1419
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:
When I press the second button I see this result:
So, Rect2
stays at the original position.
Upvotes: 2