刷新()导致我的图形闪烁

时间:2015-05-01 17:59:43

标签: c# winforms windows-forms-designer

这是我的代码:

    int i = 0;
    public Form1()
    {
        InitializeComponent();
    }


    Graphics gObject;
    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        gObject = panel1.CreateGraphics();
    }

    void DrawLines(Graphics gObject, Pen pPen)
    {
        Point pPoint1 = new Point(this.Bounds.Width / 2, 0);
        Point pPoint2 = new Point(this.Bounds.Width / 2 - this.Bounds.Width / 4, 0);
        Point pPoint3 = new Point(this.Bounds.Width / 2 + this.Bounds.Width / 4, 0);
        Point pPoint1a = new Point(this.Bounds.Width / 2, 1000);
        Point pPoint2a = new Point(this.Bounds.Width / 2 - this.Bounds.Width / 4, 1000);
        Point pPoint3a = new Point(this.Bounds.Width / 2 + this.Bounds.Width / 4, 1000);
        gObject.DrawLine(pPen, pPoint1, pPoint1a);
        gObject.DrawLine(pPen, pPoint2, pPoint2a);
        gObject.DrawLine(pPen, pPoint3, pPoint3a);
    }

    void DrawSlots(Graphics gObject, Pen pPen)
    {
        int WindowWidth = this.Bounds.Width;
        int WindowHeight = this.Bounds.Height;
        int RectHeight, RectWidth;
        RectHeight = 550;
        RectWidth = 350;

        Rectangle Slot1 = new Rectangle(WindowWidth / 2 - WindowWidth / 4 - RectWidth / 2+i, WindowHeight / 2 - RectHeight / 2, RectWidth, RectHeight);
        Rectangle Slot2 = new Rectangle(WindowWidth / 2 - RectWidth / 2, WindowHeight / 2 - RectHeight / 2, RectWidth, RectHeight);
        Rectangle Slot3 = new Rectangle(WindowWidth / 2 + WindowWidth / 4 - RectWidth / 2, WindowHeight / 2 - RectHeight / 2, RectWidth, RectHeight);

        gObject.DrawRectangle(pPen, Slot1);
        gObject.DrawRectangle(pPen, Slot2);
        gObject.DrawRectangle(pPen, Slot3);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        i++;
        Brush red = new SolidBrush(Color.Red);
        Pen redPen = new Pen(red, 1);

        DrawSlots(gObject, redPen);

        this.Refresh();
    }

我的问题是,每次调用Refresh时,我的矩形都会闪烁,但永远不会更新。定时器设置为每500ms滴答一次。我已经检查以确保数字正在更新,但我无法找到为什么矩形不是电影,以及为什么图形闪烁。

任何帮助都将非常感激,我已经搜索了高低的答案

2 个答案:

答案 0 :(得分:1)

你正以错误的方式画画。图纸应在面板上的Paint事件中完成,而不是在Timer_Tick事件中。您只应调用面板的Invalidate方法强制重绘。试试这个:

int i = 0;
public Form1() {
    InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e) {
    DrawSlots(e.Graphics, Pens.Red);
}

void DrawLines(Graphics gObject, Pen pPen) {
    Point pPoint1 = new Point(this.Bounds.Width / 2, 0);
    Point pPoint2 = new Point(this.Bounds.Width / 2 - this.Bounds.Width / 4, 0);
    Point pPoint3 = new Point(this.Bounds.Width / 2 + this.Bounds.Width / 4, 0);
    Point pPoint1a = new Point(this.Bounds.Width / 2, 1000);
    Point pPoint2a = new Point(this.Bounds.Width / 2 - this.Bounds.Width / 4, 1000);
    Point pPoint3a = new Point(this.Bounds.Width / 2 + this.Bounds.Width / 4, 1000);
    gObject.DrawLine(pPen, pPoint1, pPoint1a);
    gObject.DrawLine(pPen, pPoint2, pPoint2a);
    gObject.DrawLine(pPen, pPoint3, pPoint3a);
}

void DrawSlots(Graphics gObject, Pen pPen) {
    int WindowWidth = this.Bounds.Width;
    int WindowHeight = this.Bounds.Height;
    int RectHeight, RectWidth;
    RectHeight = 550;
    RectWidth = 350;

    Rectangle Slot1 = new Rectangle(WindowWidth / 2 - WindowWidth / 4 - RectWidth / 2 + i, WindowHeight / 2 - RectHeight / 2, RectWidth, RectHeight);
    Rectangle Slot2 = new Rectangle(WindowWidth / 2 - RectWidth / 2, WindowHeight / 2 - RectHeight / 2, RectWidth, RectHeight);
    Rectangle Slot3 = new Rectangle(WindowWidth / 2 + WindowWidth / 4 - RectWidth / 2, WindowHeight / 2 - RectHeight / 2, RectWidth, RectHeight);

    gObject.DrawRectangle(pPen, Slot1);
    gObject.DrawRectangle(pPen, Slot2);
    gObject.DrawRectangle(pPen, Slot3);
}

private void timer1_Tick(object sender, EventArgs e) {
    i++;
    this.panel1.Invalidate();
}

修改

闪烁的事情是在每次Invalidate调用(在计时器中)重新绘制整个控件的结果。当控件重新绘制自身时,OnPaintBackground方法绘制控件的背景,然后在绘图事件处理程序中,您的绘图工作再次发生。

要避免此问题,您只需要使需要重新绘制的区域无效。您可以使用另一个接收区域的Invalidate重载,并将无效区域传递给它。

答案 1 :(得分:0)

我认为你正在寻找suspendLayout和resumeLayout。通常它们会停止大多数闪烁。只需在您之前和之后进行UI更新之前包装您的事件,这通常可以解决问题。

private void panel1_Paint(object sender, PaintEventArgs e) {
// Suspend the form layout and do your activites 
   this.SuspendLayout();
    DrawSlots(e.Graphics, Pens.Red);

   this.ResumeLayout();
}