PaintEvent not overpainting

前端 未结 3 1981
北荒
北荒 2021-01-21 23:37

I have a Windows Forms application in C# with drawing panel and a button - for drawing a line.

When you click the button, you can draw a line for 2 random points.

相关标签:
3条回答
  • 2021-01-21 23:54
    1. You need to trigger a repaint event after the mouse is let go. Just call drawPanel.Invalidate() to cause the form to be redrawn.

    2. To draw multiple lines, you'll have to store the information for each one in a list or something, and draw each line in your repaint. The Paint method basically starts with a blank space each time, so it will only draw the most recent the way you currently have it set up.

    0 讨论(0)
  • 2021-01-21 23:58

    You have to call the Invalidate method on the panel:

    private void drawPanel_MouseUp(object sender, MouseEventArgs e)
    {
      onMouseUpFlag = true;
      drawPanel.Invalidate();
    }
    

    Also, use the Graphic object from the PaintEvent:

    private void drawPanel_Paint(object sender, PaintEventArgs e)
    {
      if (onMouseUpFlag)
      {
        e.Graphics.DrawLine(p, ps, pe); 
      }
    } 
    

    For multiple lines, you would have to hold the points in a collection object.

    Per your updated code, here is a working example of what I think you are trying to do:

    private class Line {
      public Point Starting { get; set; }
      public Point Ending { get; set; }
    
      public Line(Point starting, Point ending) {
        this.Starting = starting;
        this.Ending = ending;
      }
    }
    List<Line> lines = new List<Line>();
    
    private Point downPoint = Point.Empty;
    private Point movePoint = Point.Empty;
    private bool movingLine = false;
    
    public Form1() {
      InitializeComponent();
    
      panel1.Paint += panel1_Paint;
      panel1.MouseDown += panel1_MouseDown;
      panel1.MouseMove += panel1_MouseMove;
      panel1.MouseUp += panel1_MouseUp;
    }
    
    void panel1_MouseDown(object sender, MouseEventArgs e) {
      if (e.Button == MouseButtons.Left) {
        downPoint = e.Location;
      }
    }
    
    void panel1_MouseMove(object sender, MouseEventArgs e) {
      if (e.Button == MouseButtons.Left) {
        movingLine = true;
        movePoint = e.Location;
        panel1.Invalidate();
      }
    }
    
    void panel1_MouseUp(object sender, MouseEventArgs e) {
      if (e.Button == MouseButtons.Left) {
        movingLine = false;
        lines.Add(new Line(downPoint, e.Location));
        panel1.Invalidate();
      }
    }
    
    void panel1_Paint(object sender, PaintEventArgs e) {
      e.Graphics.Clear(Color.White);
      foreach (Line l in lines) {
        e.Graphics.DrawLine(Pens.Black, l.Starting, l.Ending);
      }
    
      if (movingLine) {
        e.Graphics.DrawLine(Pens.Black, downPoint, movePoint);
      }
    
    }
    

    Use an inherited panel to turn on the DoubleBuffer property to avoid flickering.

    0 讨论(0)
  • 2021-01-22 00:03

    Whenever you want to redraw (in your code) you should call panelinvalidate drawPanel.Invalidate().

    When you finish mouse moving and release the button

    private void drawPanel_MouseUp(object sender, MouseEventArgs e)
    {
                onMouseUpFlag = true;
                drawPanel.Invalidate();
    }
    

    And at the end I would suggest to use this code in your drawPanel_Paint instead of that of yours . You should use Graphics provided by an EventArgs, not create new one.

    private void drawPanel_Paint(object sender, PaintEventArgs e)
    {
                if (onMouseUpFlag)
                {
                      e.Graphics.DrawLine(p, ps, pe); 
                }
    }
    
    0 讨论(0)
提交回复
热议问题