0

I'm trying out wpf and i want to be able to create shapes by left clicking, but have the right click remove the shape the mouse-pointer is currently hovering over, however, what happens instead is the last shape created is removed. How do I fix this?

This creates the shape:

 private List<Shape> shapes = new List<Shape>();
    private Shape shape;
    public static Random rand = new Random();

    private Rectangle CreateRectangle()
    {

        int height = rand.Next(0, 151);
        int width = rand.Next(0, 101);
        byte alpha = (byte)rand.Next(0, 256);
        byte alpha2 = (byte)rand.Next(0, 256);
        byte alpha3 = (byte)rand.Next(0, 256);
        Rectangle rect = new Rectangle();
        rect.Width = width;
        rect.Height = height;
        SolidColorBrush color = new SolidColorBrush();
        color.Color = Color.FromRgb(alpha, alpha2, alpha3);
        rect.Fill = color;
        return rect;
    }

    private Ellipse CreateEllipse()
    {

        int height = rand.Next(0, 151);
        int width = rand.Next(0, 101);
        byte alpha = (byte)rand.Next(0, 256);
        byte alpha2 = (byte)rand.Next(0, 256);
        byte alpha3 = (byte)rand.Next(0, 256);
        Ellipse ellipse = new Ellipse();
        ellipse.Width = width;
        ellipse.Height = height;
        SolidColorBrush color = new SolidColorBrush();
        color.Color = Color.FromRgb(alpha, alpha2, alpha3);
        ellipse.Fill = color;
        return ellipse;

    }

    private void ColumnDefinition_OnClick(object sender, MouseButtonEventArgs e)
    {
        Point area = System.Windows.Input.Mouse.GetPosition(mc);
        int num = rand.Next(1, 3);
        switch (num)
        {
            case 1:
              shape = CreateRectangle();

                mc.Children.Add(shape);
                shapes.Add(shape);
                Canvas.SetLeft(shape, area.X);
                Canvas.SetTop(shape, area.Y);
                break;
            case 2:
                shape = CreateEllipse();
                 mc.Children.Add(shape);
                shapes.Add(shape);
                Canvas.SetLeft(shape, area.X);
                Canvas.SetTop(shape, area.Y);
                break;
        }
    }

    private void Clear_Click(object sender, RoutedEventArgs e)
    {
        mc.Children.Clear();
    }

This is whats supposed to remove the shape:

    private void mc_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {

        mc.Children.Remove(shape);
        shapes.Remove(shape);
    }
}

}

Any help is greatly appreciated.

MehLdy
  • 57
  • 1
  • 7

3 Answers3

0

I'm not sure I have everything I need in the code example, but it looks like a shape is being created and added to a list, but also assigned to a member named "shape" which is being overwritten by the newest shape created. You are then always removing that newest shape. You should attach a mousedown handler to each shape, capture the shape from the object sender, and remove it from the list.

private void shape_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    Shape s = sender as Shape;
    mc.Children.Remove(s);
    shapes.Remove(s);
}
SolidSloth
  • 83
  • 2
  • 9
0

I recommend you to learn hit testing in WPF. Look at this question where I answered how to get geometry under mouse and remove it. You just need to adapt this code for your task but it is super easy.

XAML:

<Canvas Mouse.MouseDown="Canvas_MouseDown">

Code behind:

private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
    var canvas = sender as Canvas;
    if (canvas == null)
        return;

    HitTestResult hitTestResult = VisualTreeHelper.HitTest(canvas, e.GetPosition(canvas));
    var shape = hitTestResult.VisualHit as Shape;
    if (shape == null)
        return;

    canvas.Children.Remove(shape);
    shapes.Remove(shape); // I think you don't need list of shapes
}
Maxim
  • 1,995
  • 1
  • 19
  • 24
0

The MouseButtonEventArgs.OriginalSource property returns the clicked Shape so you could implement your mc_MouseRightButtonDown event handler like this:

private void mc_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    Shape clickedShape = e.OriginalSource as Shape;
    if (clickedShape != null)
    {
        mc.Children.Remove(clickedShape);
        shapes.Remove(clickedShape);
    }
}
mm8
  • 163,881
  • 10
  • 57
  • 88