1

I'm trying to use the following code to allow the user to draw a rectangle around something on the screen, to select that area.

public partial class MainWindow : Window
{
    public enum DrawMode
    {
        Move,
        Draw
    }

    private DrawMode _drawmode;
    private Point _startPoint;
    private Rectangle _rectangle;
    public MainWindow()
    {
        _rectangle = new Rectangle();
        _rectangle.Stroke = new SolidColorBrush(Colors.Black);
        _rectangle.StrokeThickness = 1;
        InitializeComponent();
    }

    private void MapImageOnMouseDown(object sender, MouseButtonEventArgs e)
    {
        _drawmode = DrawMode.Draw;
        _startPoint = e.GetPosition(DrawCanvas);
    }

    private void MapImageOnMouseUp(object sender, MouseButtonEventArgs e)
    {
        _drawmode = DrawMode.Move;
    }

    private void MapImageOnMouseMove(object sender, MouseEventArgs e)
    {
        if (_drawmode == DrawMode.Draw)
        {
            DrawCanvas.Children.Remove(_rectangle);
            var endPoint = e.GetPosition(DrawCanvas);
            var width = Math.Abs(endPoint.X - _startPoint.X);
            var height = Math.Abs(endPoint.Y - _startPoint.Y);
            _rectangle.Width = width;
            _rectangle.Height = height;
            DrawCanvas.Children.Add(_rectangle);
            Canvas.SetTop(_rectangle, _startPoint.X);
            Canvas.SetLeft(_rectangle, _startPoint.Y);
        }
    }
}

However, although when I mousedown, the top left of the rectangle is nowhere near the point that I mousedown at. Are there different coordinate systems or something?

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • http://tech.pro/tutorial/893/wpf-snippet-reliably-getting-the-mouse-position – Arie Oct 14 '14 at 07:01
  • http://stackoverflow.com/questions/16434356/draw-rectangle-when-mouse-dragged-using-mvvm-in-wpf?rq=1 – Gilad Dec 31 '14 at 16:00

2 Answers2

1

You have confused X and Y (or Left and Top). Change

Canvas.SetTop(_rectangle, _startPoint.X);
Canvas.SetLeft(_rectangle, _startPoint.Y);

to

Canvas.SetLeft(_rectangle, _startPoint.X);
Canvas.SetTop(_rectangle, _startPoint.Y);

It is also not necessary to remove and add the Rectangle each time its position changes:

public MainWindow()
{
    InitializeComponent();

    _rectangle = new Rectangle
    {
        Stroke = Brushes.Black,
        StrokeThickness = 1
    };

    DrawCanvas.Children.Add(_rectangle); // add it once
}

private void MapImageOnMouseMove(object sender, MouseEventArgs e)
{
    if (_drawmode == DrawMode.Draw)
    {
        var endPoint = e.GetPosition(DrawCanvas);
        _rectangle.Width = Math.Abs(endPoint.X - _startPoint.X);
        _rectangle.Height = Math.Abs(endPoint.Y - _startPoint.Y);
        Canvas.SetLeft(_rectangle, Math.Min(_startPoint.X, endPoint.X));
        Canvas.SetTop(_rectangle, Math.Min(_startPoint.Y, endPoint.Y));
    }
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
0
    Point startPoint = new Point(0, 0);
    Point endPoint = new Point(1, 1);
    bool mousePress = false;
    control.MouseDown += (s, e) =>
    {
            startPoint = new Point(e.X,e.Y);
            mousePress = true;
    };
    control.MouseUp += (s, e) =>
    {
            mousePress = false;
    };
    control.MouseMove += (s, e) =>
    {
            if (mousePress)
            {
                endPoint = new Point(e.X, e.Y);
                control.Invalidate();
            }
    };
    control.Paint += (s, e) =>
    {
            Graphics g = e.Graphics;
            g.DrawRectangle(Pens.Black, new Rectangle(startPoint.X, startPoint.Y,endPoint.X-startPoint.X, endPoint.Y-startPoint.Y));
    };

I have been doing drawing in the past and this worked for me for rectangles, dont know how it translates to wpf tho

Vajura
  • 1,112
  • 7
  • 16
  • What is `control`? My `Canvas`? – ProfK Oct 14 '14 at 07:42
  • The control you are drawing on – Vajura Oct 14 '14 at 07:49
  • Works well in WinForms, will try it in WPF - it's simpler than mine. One lingering problem I think most rectangle drawing code has ,though, it only draws right and down. You can't draw left and up. – ProfK Oct 14 '14 at 08:17
  • Unfortunately, the `Canvas` drawing surface in WPF has no `Paint` event, and I find nothing similar looking, but thanks, I'll bookmark this for when I find equivalents. – ProfK Oct 14 '14 at 08:25