Home > Software engineering >  how do i rotate a shape derived class created dynamically, with the mouse in wpf?
how do i rotate a shape derived class created dynamically, with the mouse in wpf?

Time:07-12

i want something like this but i want to create the control dynamically and probably not a user control. So far i got to this:

private void Shape_MouseMove(object sender, MouseEventArgs e)
{
Shape? obj = sender as Shape;

if (obj != null)
{
   if (e.LeftButton == MouseButtonState.Pressed)
       {
            if (obj.IsMouseCaptured)
                {
                    if (!(obj is Path))
                    {
                        if (Keyboard.Modifiers == ModifierKeys.Shift)
                        {
                            Point ptCenter = new Point(obj.ActualWidth / obj.ActualHeight / 2);
                            Point pt = Mouse.GetPosition(obj);

                            double radians = Math.Atan2(pt.Y - ptCenter.Y, pt.X - ptCenter.X);
                            double angle = 180 * radians / Math.PI;
                            // Apply a 180 degree shift when X is negative so that we can rotate
                            // all of the way around
                            if (pt.X - ptCenter.X < 0)
                            {
                                angle  = 180;
                            }
                            RotateTransform? rt = obj.RenderTransform as RotateTransform;
                            //obj.RenderTransformOrigin = new Point(0.5, 0.5);
                            if (rt != null)
                            {
                                rt.CenterX = ptCenter.X;
                                rt.CenterY = ptCenter.Y;
                                rt.Angle = angle;
                            }
                            else
                            {
                                obj.RenderTransform = new RotateTransform()
                                {
                                    CenterX = ptCenter.X,
                                    CenterY = ptCenter.Y,
                                    Angle = angle
                                };
                            }
                            Title = angle.ToString();
                        }

Unfortunatelly it doesnt work as i want, the shapes behave erractically as i drag the mouse. .......................................................................................... ..........................................................................................

CodePudding user response:

You should not determine the mouse position relative to the rotated element, because the mouse position in the element's coordinate system takes the own RenderTransform into account.

Attach mouse event handlers to a Canvas (or other Panel) that is the parent element of the shapes. Make sure to set a Background, otherwise mouse events won't be received outside the shapes' areas.

<Canvas Background="Transparent"
        MouseLeftButtonDown="CanvasMouseLeftButtonDown"
        MouseLeftButtonUp="CanvasMouseLeftButtonUp"
        MouseMove="CanvasMouseMove">

    <!-- shapes are added to this Canvas -->
</Canvas>

The event handler may look like this:

private Shape shape;

private void CanvasMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    shape = e.OriginalSource as Shape;
}

private void CanvasMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    shape = null;
}

private void CanvasMouseMove(object sender, MouseEventArgs e)
{
    if (shape != null)
    {
        var canvas = (Canvas)sender;
        var pos = e.GetPosition(canvas);
        var center = shape.TranslatePoint(
            new Point(shape.ActualWidth / 2, shape.ActualHeight / 2),
            canvas);

        if (shape.RenderTransform is not RotateTransform transform)
        {
            transform = new RotateTransform();
            shape.RenderTransform = transform;
            shape.RenderTransformOrigin = new Point(0.5, 0.5);
        }

        transform.Angle = -Vector.AngleBetween(pos - center, new Vector(1, 0));
    }
}
  • Related