1

I have a problem using my canvas in WPF. I use a lightly modified version of this code : Draw rectangle when mouse dragged using MVVM in WPF

Here is the code :

Xaml :

<Canvas x:Name="cnvImage" Width="800">
    <Image MouseDown="img_MouseDown"
        MouseMove="img_MouseMove"
        MouseUp="img_MouseUp"
        Source="/Images/CapturedImage.png">
    </Image>
</Canvas>

C# (code behind) :

    private Point startPoint;
    private Rectangle rectSelectArea;

    private void img_MouseDown(object sender, MouseButtonEventArgs e)
    {
        startPoint = e.GetPosition(cnvImage);

        // Remove the drawn rectanglke if any.
        // At a time only one rectangle should be there
        if (rectSelectArea != null)
            cnvImage.Children.Remove(rectSelectArea);

        // Initialize the rectangle.
        // Set border color, fill and width
        rectSelectArea = new Rectangle
        {
            Stroke = Brushes.Red,
            StrokeThickness = 2,
            Fill = Brushes.Transparent

        };

        Canvas.SetLeft(rectSelectArea, startPoint.X);
        Canvas.SetTop(rectSelectArea, startPoint.Y);
        cnvImage.Children.Add(rectSelectArea);
    }

    private void img_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Released || rectSelectArea == null)
            return;

        var pos = e.GetPosition(cnvImage);

        // Set the position of rectangle
        var x = Math.Min(pos.X, startPoint.X);
        var y = Math.Min(pos.Y, startPoint.Y);

        // Set the dimension of the rectangle
        var w = Math.Max(pos.X, startPoint.X) - x;
        var h = Math.Max(pos.Y, startPoint.Y) - y;

        rectSelectArea.Width = w;
        rectSelectArea.Height = h;

        Canvas.SetLeft(rectSelectArea, x);
        Canvas.SetTop(rectSelectArea, y);
    }

    private void img_MouseUp(object sender, MouseButtonEventArgs e)
    {
         private void img_MouseUp(object sender, MouseButtonEventArgs e)
    {
        //EDIT : this condition SOLVES the problem 
        if (e.GetPosition(cnvImage) == startPoint) 
            cnvImage.Children.Remove(rectSelectArea);

        rectSelectArea = null;

    }

I want to draw Rectangles but there is a problem : if I simply left-click on the canvas, it draws a little red point that seems to be impossible to delete.

Where does this come from ? How can I get rid of it ?

EDIT : the problem has been solved.

Community
  • 1
  • 1
  • I think you need to check the position in mousedown and mouseup and if those positions are equal then you should just delete the rectangle that you have created. – Krishna Nov 25 '14 at 09:58
  • It works :D That's strange, when I had the condition "if(width<10 || height<10)" it didn't work... Since the end point and the start points are the same, my rectangle should have width = 0 and height = 0, right ? Anyway, as we say in my country, merci beaucoup ! – Jonathan B. Nov 25 '14 at 10:35
  • The problem is that you have already added a rectangle in your mousedown and set the strokethickness to 2 so you will always end up with a rectangle of a width and height of atleast 2. I will post my comment as answer and you can accept it if it helped you. Thanks – Krishna Nov 25 '14 at 10:44
  • yeah, but 2 is still lower than 10, so why ? – Jonathan B. Nov 25 '14 at 13:32
  • i dont see that if statement in the code you posted. Can you post that code please? – Krishna Nov 25 '14 at 13:42
  • I edited my code to make that appear ;) (modification in img_MouseUp) – Jonathan B. Nov 25 '14 at 14:05
  • Sorry for asking so many changes :D but can you change that to ActualWidth and ActualHeight in your if statement and try again and if that fails can you do a Console.Writeline to see what the width and height that it is reporting? – Krishna Nov 25 '14 at 14:31
  • ActualWidth/Height works ! When I do Console.WriteLine(rectSelectArea.Width + " " + rectSelectArea.ActualWidth); I get "Non-numeric 2" – Jonathan B. Nov 25 '14 at 14:43
  • Thanks. I thought the Actual Width/height would work. When you created the rectangle the height and width are not set so by default WPF sets them to NaN and the ActualWidth/height would be 2 (because of the strokethickness). I am still not sure why setting width and height in your move method is not working. – Krishna Nov 25 '14 at 14:49
  • Using ActualHeight/Width is quite useful in wpf as sometimes you set the control to stretch in your xaml and in that case the width will be NaN but your actualWidth will report the actual width for you. – Krishna Nov 25 '14 at 14:50

1 Answers1

1

I think you need to check the position in img_MouseDown and img_MouseUp and if those positions are equal then you should just delete the rectangle that you have created.

Because you are adding a rectanlge of strokethickness of 2 in your mousedown, you are always going to end up with a rectangle with an actual width and height of atleast 2 in your code.

Krishna
  • 1,956
  • 13
  • 25
  • Could you elaborate on this a bit more please? – user2697817 Nov 25 '14 at 14:56
  • I edited the code with the solution inside. You can also check if the ActualWidth and ActualHeight properties are greater than a certain number to delete or not a Rectangle, since the Width and Height properties doesn't return a numeric value. – Jonathan B. Nov 25 '14 at 16:25