-1

I am trying to code this function on a form: User click on the form, a inputbox asks user to input a name, and a circle is drawn on the place in the form where the user clicks. One issue now I faces is that circle is now draw at the place where the inputbox show up. I actually have a function to repaint every circle on the form, but it still does not work. Here is my code:

private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        string ProvinceName;
        System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Red);
        System.Drawing.Graphics formGraphics;
        formGraphics = this.CreateGraphics();

        formGraphics.FillEllipse(myBrush, new Rectangle(e.X, e.Y, 10, 10));

        ProvinceName = Microsoft.VisualBasic.Interaction.InputBox("郡名", "", "无名",100,100);

        provinces.Add(new province(ProvinceName, e.X, e.Y));

        listBox1.SelectedIndex = provinces.Count - 1;

        myBrush.Dispose();
        formGraphics.Dispose();
        PaintMap();// This is the function repaint every recorded clicked locations.

    }
Jacobier
  • 1
  • 2
  • Don't use an InputBox then. You can build a similar Form for the same task, so you can place it wherever you need to without effort (and it won't clear the current drawing). The Form could be borderless and it could close when you press Enter. I assume that the `PaintMap()` method repaints the entire collection of `Points` and names you have stored in `provinces` in the Form's `Paint` event. Is it? – Jimi Feb 13 '20 at 04:13
  • _formGraphics = this.CreateGraphics();_ - Winforms graphics basic rule #1 : Never use `control.CreateGraphics`! Never try to cache a `Graphics` object! Either draw into a `Bitmap bmp` using a `Graphics g = Graphics.FromImage(bmp)` or in the `Paint` event of a control, using the `e.Graphics` parameter.. – TaW Feb 13 '20 at 07:17
  • @TaW If I use Paint event, how can I control the painting with the mouse? Can you show me or give me some link to teach how the Bitmap thing work? I am a beginner. – Jacobier Feb 13 '20 at 17:51
  • Use the mouse events to change or expand the data you use in the paint event and call Invalidate to trigger Paint ! – TaW Feb 13 '20 at 17:53
  • I did. And the result is even worse. The circles outside of the range of the inputbox are all gone. – Jacobier Feb 13 '20 at 18:17
  • All elements you draw must be drawn each time! There is no other way to create persistent and repsonsive graphics. [Example](https://stackoverflow.com/questions/36924016/how-to-draw-multiple-ellipse-in-the-same-panel/36924235?r=SearchResults&s=5|34.9170#36924235) - [Many more examples](https://stackoverflow.com/search?q=user%3A3152130+drawaction) – TaW Feb 13 '20 at 18:35
  • See the simple example here: [How to call a method that uses PaintEventArgs and coordinates variables](https://stackoverflow.com/a/53708936/7444103). You just need to draw an ellipse instead of a rectangle. You can draw a non-persistent object using `CreateGraphics()`. It will be clear as soon as you call `Invalidate()`. Or something *covers* it. Or the Control used as canvas is *obscured* by something else. Or the Form is repainted. For example when another Form is moved over it or it's minimized/maximized or moved outside the Screen bounds or... – Jimi Feb 13 '20 at 19:18

2 Answers2

1

Just drawing it is not enough. Every time the form is redrawn it will need to be painted again. The first step would be to override OnPaint

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    // paint your circles here, when they need to be persisted 
    // e.Graphics.DrawRectangle(redPen, r);
}

Obviously you will need to keep track of what needs to be drawn, and when it no longer needs to be drawn, however this should get you started

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
0

I used Bipmap to store the paint and then use paint event to repaint the form. The problem is solved. I think when I directly use "System.Drawing, I paint on the inputbox.

Jacobier
  • 1
  • 2