-1

I'm trying to draw a vertical line when the mouse moves over a panel:

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
    Panel panel = sender as Panel;
    if (panel != null)
    {
        using (Graphics g = panel.CreateGraphics())
        {
            using (Pen pen = new Pen(Color.Red))
            {
                g.DrawLine(pen, e.X, 0, e.X, panel.Height);
            }
        }
        panel.Invalidate(true);
    }
}

But nothing is drawn.

What am I doing wrong?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Alex
  • 583
  • 5
  • 18
  • 2
    Doesn't calling `Invalidate` forces a redraw, thus erasing your drawn graphics? Better do your painting in the `Paint` event handler. – Uwe Keim Feb 02 '19 at 16:25
  • 1
    `control.CreateGraphics())` will result in __non-persistent__ drawing. Which means it will be cleared once the system or your code triggers redrawing. Which you do with the Invalidate command. Delete that line and the line will be visible, but not persist. Move it off the screen and it will be gone.. Usually you will want ot draw only in the Paint event, as others have noted. – TaW Feb 02 '19 at 17:09
  • 1
    - `control.CreateGraphics())` can be useful for live drawing of rubberband lines or other moving stuff. Or for some measurements. - Also note that panels ought to be [doubleBuffered](https://stackoverflow.com/questions/44185298/update-datagridview-very-frequently/44188565#44188565) to avoid flicker! – TaW Feb 02 '19 at 17:12

1 Answers1

3

All GDI drawing has to be done inside the .Paint() event using the Graphics object that is supplied inside the PaintEventArgs argument. Use the .MouseMove() to store the mouse values, and trigger a paint event.

Try this:

public partial class Form1 : Form
{
    Point mouse;
    MouseButtons buttons;

    public Form1()
    {
        InitializeComponent();
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        if (sender is Panel panel)
        {
            var g = e.Graphics;
            g.DrawLine(Pens.Red, mouse.X, 0, mouse.X, panel.Height);
        }
    }

    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
        mouse=e.Location;
        buttons=e.Button;

        panel1.Refresh();
    }
}

Here is the result:

scr

John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • You could improve this a bit by storing the pen in an instance variable so it doesn't need to be created and disposed this often. – Emond Feb 02 '19 at 17:18
  • 2
    Creating a Pen is dirt cheap. The actual recommended way would be to use `Pens.Red`. - But actually this question should not be answered but closed as duplicate (of hundreds of other posts) and deleted. – TaW Feb 02 '19 at 17:38
  • 1
    @TaW - As it stands now the question is not marked as duplicate, so I was happy to help the _OP_ with an easy answer. You are free to nitpick at the answer, but the fact remains that my answer instructs the _OP_ on how to do GDI drawing, which is what he was looking for (I think). – John Alexiou Feb 03 '19 at 17:04
  • @alex - note that drawing on a `Panel` might cause flicker. Try using a `PictureBox` instead. – John Alexiou Mar 26 '19 at 00:13