使用paint方法在面板上绘制矩形时如何避免闪烁?

时间:2014-12-02 11:12:33

标签: c# winforms

    public Form1()
    {
        InitializeComponent();
        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        SetStyle(ControlStyles.UserMouse, true);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);


        //this.SetStyle(ControlStyles.UserPaint, true);
        //this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        //this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);


        this.DoubleBuffered = true;

        Rect1LT.Width = 10;
        Rect1LT.Height = 10;
        Rect1L.Width = 10;
        Rect1L.Height = 10;
        Rect1RT.Width = 10;
        Rect1RT.Height = 10;
        Rect1B.Width = 10;
        Rect1B.Height = 10;
        Rect1RB.Width = 10;
        Rect1RB.Height = 10;
        Rect1R.Width = 10;
        Rect1R.Height = 10;
        Rect1LB.Width = 10;
        Rect1LB.Height = 10;
        Rect1T.Width = 10;
        Rect1T.Height = 10;

        Rect1.X = panel1.Location.X + 50;
        Rect1.Y = panel1.Location.Y + 50;
        Rect1.Width = 100;
        Rect1.Height = 100;

        Rect1LT.X = Rect1.X - 5;
        Rect1LT.Y = Rect1.Y - 5;

        Rect1RT.X = Rect1.X - 5 + Rect1.Width;
        Rect1RT.Y = Rect1.Y - 5;

        Rect1LB.X = Rect1.X - 5;
        Rect1LB.Y = Rect1.Y - 5 + Rect1.Height;

        Rect1RB.X = Rect1.X - 5 + Rect1.Width;
        Rect1RB.Y = Rect1.Y - 5 + Rect1.Height;

        Rect1T.X = Rect1.X - 5 + (Rect1.Width / 2);
        Rect1T.Y = Rect1.Y - 5;

        Rect1B.X = Rect1.X - 5 + (Rect1.Width / 2);
        Rect1B.Y = Rect1.Y - 5 + Rect1.Height;

        Rect1L.X = Rect1.X - 5;
        Rect1L.Y = Rect1.Y - 5 + (Rect1.Height / 2);

        Rect1R.X = Rect1.X - 5 + Rect1.Width;
        Rect1R.Y = Rect1.Y - 5 + (Rect1.Height / 2);



    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {


    Pen mypen = default(Pen);
    mypen = new Pen(System.Drawing.Color.Red, 3);
    mypen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
    //For Dash Line in Rectangle 
    Pen mypen1 = default(Pen);
    mypen1 = new Pen(System.Drawing.Color.Blue, 1);
    mypen1.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

    L1 = Rect1LT.X + 5;
    T1 = Rect1LT.Y + 5;
    W1 = Rect1RB.X - Rect1LT.X;
    H1 = Rect1RB.Y - Rect1LT.Y;
    e.Graphics.DrawRectangle(mypen, new System.Drawing.Rectangle(L1, T1, W1, H1));
    e.Graphics.DrawRectangle(mypen1, new System.Drawing.Rectangle(L1, T1, W1, H1));

    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LT.X, Rect1LT.Y, 10, 10));
    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RT.X, Rect1RT.Y, 10, 10));
    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LB.X, Rect1LB.Y, 10, 10));
    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RB.X, Rect1RB.Y, 10, 10));

    e.Graphics.FillRectangle(Brushes.Blue, Rect1LT);
    e.Graphics.FillRectangle(Brushes.Blue, Rect1RT);
    e.Graphics.FillRectangle(Brushes.Blue, Rect1LB);
    e.Graphics.FillRectangle(Brushes.Blue, Rect1RB);

    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1T.X, Rect1T.Y, 10, 10));
    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1R.X, Rect1R.Y, 10, 10));
    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1B.X, Rect1B.Y, 10, 10));
    e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1L.X, Rect1L.Y, 10, 10));

    e.Graphics.FillRectangle(Brushes.Blue, Rect1T);
    e.Graphics.FillRectangle(Brushes.Blue, Rect1R);
    e.Graphics.FillRectangle(Brushes.Blue, Rect1B);
    e.Graphics.FillRectangle(Brushes.Blue, Rect1L);


}

int L1;
int T1;
int W1;
int H1;
bool flg1_LT = false;
bool flg1_RT = false;
bool flg1_LB = false;
bool flg1_RB = false;
bool flg1_mid = false;
bool flg1_T = false;
bool flg1_B = false;
bool flg1_L = false;

bool flg1_R = false;
public System.Drawing.Rectangle Rect1;
public System.Drawing.Rectangle Rect1LT;
public System.Drawing.Rectangle Rect1RT;
public System.Drawing.Rectangle Rect1LB;
public System.Drawing.Rectangle Rect1RB;
public System.Drawing.Rectangle Rect1T;
public System.Drawing.Rectangle Rect1B;
public System.Drawing.Rectangle Rect1L;

public System.Drawing.Rectangle Rect1R;
public Point Point1LT;
public Point Point1RT;
public Point Point1LB;
public Point Point1RB;
public Point Point1L;
public Point Point1T;
public Point Point1R;

public Point Point1B;

private void panel1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Location.X >= Rect1LT.X & e.Location.Y >= Rect1LT.Y & e.Location.X <= (Rect1LT.X + 10) & e.Location.Y <= (Rect1LT.Y + 10))
    {
        flg1_LT = true;
    }
    else if (e.Location.X >= Rect1RT.X & e.Location.Y >= Rect1RT.Y & e.Location.X <= (Rect1RT.X + 10) & e.Location.Y <= (Rect1RT.Y + 10))
    {
        flg1_RT = true;
    }
    else if (e.Location.X >= Rect1LB.X & e.Location.Y >= Rect1LB.Y & e.Location.X <= (Rect1LB.X + 10) & e.Location.Y <= (Rect1LB.Y + 10))
    {
        flg1_LB = true;
    }
    else if (e.Location.X >= Rect1RB.X & e.Location.Y >= Rect1RB.Y & e.Location.X <= (Rect1RB.X + 10) & e.Location.Y <= (Rect1RB.Y + 10))
    {
        flg1_RB = true;
    }
    else if (e.Location.X >= Rect1B.X & e.Location.Y >= Rect1B.Y & e.Location.X <= (Rect1B.X + 10) & e.Location.Y <= (Rect1B.Y + 10))
    {
        flg1_B = true;
    }
    else if (e.Location.X >= Rect1R.X & e.Location.Y >= Rect1R.Y & e.Location.X <= (Rect1R.X + 10) & e.Location.Y <= (Rect1R.Y + 10))
    {
        flg1_R = true;
    }
    else if (e.Location.X >= Rect1T.X & e.Location.Y >= Rect1T.Y & e.Location.X <= (Rect1T.X + 10) & e.Location.Y <= (Rect1T.Y + 10))
    {
        flg1_T = true;
    }
    else if (e.Location.X >= Rect1L.X & e.Location.Y >= Rect1L.Y & e.Location.X <= (Rect1L.X + 10) & e.Location.Y <= (Rect1L.Y + 10))
    {
        flg1_L = true;
    }
    else if (e.Location.X >= (Rect1LT.X + 10) & e.Location.Y >= (Rect1LT.Y + 10) & e.Location.X <= (Rect1RB.X + 10) & e.Location.Y <= (Rect1RB.Y + 10))
    {
        flg1_mid = true;

        temp1X = e.Location.X;
        temp1Y = e.Location.Y;

        Point1L.X = Rect1L.X;
        Point1T.X = Rect1T.X;
        Point1B.X = Rect1B.X;
        Point1R.X = Rect1R.X;
        Point1L.Y = Rect1L.Y;
        Point1T.Y = Rect1T.Y;
        Point1B.Y = Rect1B.Y;
        Point1R.Y = Rect1R.Y;
        Point1LT.X = Rect1LT.X;
        Point1LB.X = Rect1LB.X;
        Point1RT.X = Rect1RT.X;
        Point1RB.X = Rect1RB.X;
        Point1LT.Y = Rect1LT.Y;
        Point1LB.Y = Rect1LB.Y;
        Point1RT.Y = Rect1RT.Y;
        Point1RB.Y = Rect1RB.Y;

        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeAll;
}


}
int temp1X;
int temp1Y;
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
    System.Drawing.Rectangle Rect_TEMP1 = default(System.Drawing.Rectangle);
    System.Drawing.Rectangle Rect_TEMP2 = default(System.Drawing.Rectangle);
    System.Drawing.Rectangle Rect_TEMP3 = default(System.Drawing.Rectangle);
    System.Drawing.Rectangle Rect_TEMP4 = default(System.Drawing.Rectangle);
    System.Drawing.Rectangle Rect_TEMP5 = default(System.Drawing.Rectangle);
    System.Drawing.Rectangle Rect_TEMP6 = default(System.Drawing.Rectangle);

    if (e.Button == MouseButtons.Left)
    {
        Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
        Rect1L.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
        Rect1R.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
        Rect1B.X = ((Rect1LT.X + Rect1RB.X) / 2);


        if (flg1_LT)
        {
            if (e.Location.X > Rect1LT.X)
            {
                Rect1LT.X = e.Location.X;
                Rect1LB.X = e.Location.X;
                Rect1L.X = e.Location.X;
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y > Rect1LT.Y)
            {
                Rect1LT.Y = e.Location.Y;
                Rect1RT.Y = e.Location.Y;
                Rect1T.Y = e.Location.Y;
                Rect1L.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }
            if (e.Location.X < Rect1LT.X)
            {
                Rect1LT.X = e.Location.X;
                Rect1LB.X = e.Location.X;
                Rect1L.X = e.Location.X;
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y < Rect1LT.Y)
            {
                Rect1LT.Y = e.Location.Y;
                Rect1RT.Y = e.Location.Y;
                Rect1T.Y = e.Location.Y;
                Rect1L.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }



        }
        else if (flg1_RT)
        {
            if (e.Location.X > Rect1RT.X)
            {
                Rect1RT.X = e.Location.X;
                Rect1RB.X = e.Location.X;
                Rect1R.X = e.Location.X;
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y > Rect1RT.Y)
            {
                Rect1RT.Y = e.Location.Y;
                Rect1LT.Y = e.Location.Y;
                Rect1T.Y = e.Location.Y;
                Rect1R.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }
            if (e.Location.X < Rect1RT.X)
            {
                Rect1RT.X = e.Location.X;
                Rect1RB.X = e.Location.X;
                Rect1R.X = e.Location.X;
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y < Rect1RT.Y)
            {
                Rect1RT.Y = e.Location.Y;
                Rect1LT.Y = e.Location.Y;
                Rect1T.Y = e.Location.Y;
                Rect1R.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }


        }
        else if (flg1_LB)
        {
            if (e.Location.X > Rect1LB.X)
            {
                Rect1LB.X = e.Location.X;
                Rect1LT.X = e.Location.X;
                Rect1L.X = e.Location.X;
                Rect1B.X = ((Rect1LT.X + Rect1RB.X) / 2);
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y > Rect1LB.Y)
            {
                Rect1LB.Y = e.Location.Y;
                Rect1RB.Y = e.Location.Y;
                Rect1B.Y = e.Location.Y;
                Rect1L.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }
            if (e.Location.X < Rect1LB.X)
            {
                Rect1LB.X = e.Location.X;
                Rect1LT.X = e.Location.X;
                Rect1L.X = e.Location.X;
                Rect1B.X = ((Rect1LT.X + Rect1RB.X) / 2);
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y < Rect1LB.Y)
            {
                Rect1LB.Y = e.Location.Y;
                Rect1RB.Y = e.Location.Y;
                Rect1B.Y = e.Location.Y;
                Rect1L.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }


        }
        else if (flg1_RB)
        {
            if (e.Location.X > Rect1RB.X)
            {
                Rect1RB.X = e.Location.X;
                Rect1RT.X = e.Location.X;
                Rect1R.X = e.Location.X;
                Rect1B.X = ((Rect1LT.X + Rect1RB.X) / 2);
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y > Rect1RB.Y)
            {
                Rect1RB.Y = e.Location.Y;
                Rect1LB.Y = e.Location.Y;
                Rect1B.Y = e.Location.Y;
                Rect1R.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }
            if (e.Location.X < (Rect1RB.X + 10))
            {
                Rect1RB.X = e.Location.X;
                Rect1RT.X = e.Location.X;
                Rect1R.X = e.Location.X;
                Rect1B.X = ((Rect1LT.X + Rect1RB.X) / 2);
                Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
            }
            if (e.Location.Y < (Rect1RB.Y + 10))
            {
                Rect1RB.Y = e.Location.Y;
                Rect1LB.Y = e.Location.Y;
                Rect1B.Y = e.Location.Y;
                Rect1R.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
            }


        }
        else if (flg1_B)
        {
            if (e.Location.Y > Rect1B.Y)
            {
                Rect1B.Y = e.Location.Y;
                Rect1LB.Y = e.Location.Y;
                Rect1RB.Y = e.Location.Y;
            }
            if (e.Location.Y < (Rect1B.Y + 10))
            {
                Rect1B.Y = e.Location.Y;
                Rect1LB.Y = e.Location.Y;
                Rect1RB.Y = e.Location.Y;
            }


        }
        else if (flg1_T)
        {
            if (e.Location.Y > Rect1T.Y)
            {
                Rect1T.Y = e.Location.Y;
                Rect1LT.Y = e.Location.Y;
                Rect1RT.Y = e.Location.Y;
            }

            if (e.Location.Y < (Rect1T.Y + 10))
            {
                Rect1T.Y = e.Location.Y;
                Rect1LT.Y = e.Location.Y;
                Rect1RT.Y = e.Location.Y;
            }


        }
        else if (flg1_R)
        {
            if (e.Location.X > Rect1R.X)
            {
                Rect1R.X = e.Location.X;
                Rect1RT.X = e.Location.X;
                Rect1RB.X = e.Location.X;
            }

            if (e.Location.X < (Rect1R.X + 10))
            {
                Rect1R.X = e.Location.X;
                Rect1RT.X = e.Location.X;
                Rect1RB.X = e.Location.X;
            }


        }
        else if (flg1_L)
        {
            if (e.Location.X > Rect1L.X)
            {
                Rect1L.X = e.Location.X;
                Rect1LT.X = e.Location.X;
                Rect1LB.X = e.Location.X;
            }

            if (e.Location.X < (Rect1L.X + 10))
            {
                Rect1L.X = e.Location.X;
                Rect1LT.X = e.Location.X;
                Rect1LB.X = e.Location.X;
            }


        }
        else if (flg1_mid)
        {
            Rect1LT.X = Point1LT.X + (e.Location.X - temp1X);
            Rect1RT.X = Point1RT.X + (e.Location.X - temp1X);
            Rect1LB.X = Point1LB.X + (e.Location.X - temp1X);
            Rect1RB.X = Point1RB.X + (e.Location.X - temp1X);
            Rect1LT.Y = Point1LT.Y + (e.Location.Y - temp1Y);
            Rect1RT.Y = Point1RT.Y + (e.Location.Y - temp1Y);
            Rect1LB.Y = Point1LB.Y + (e.Location.Y - temp1Y);
            Rect1RB.Y = Point1RB.Y + (e.Location.Y - temp1Y);
            Rect1L.X = Point1L.X + (e.Location.X - temp1X);
            Rect1R.X = Point1R.X + (e.Location.X - temp1X);
            Rect1B.X = Point1B.X + (e.Location.X - temp1X);
            Rect1T.X = Point1T.X + (e.Location.X - temp1X);
            Rect1L.Y = Point1L.Y + (e.Location.Y - temp1Y);
            Rect1R.Y = Point1R.Y + (e.Location.Y - temp1Y);
            Rect1B.Y = Point1B.Y + (e.Location.Y - temp1Y);
            Rect1T.Y = Point1T.Y + (e.Location.Y - temp1Y);

        }

        Rect1T.X = ((Rect1LT.X + Rect1RB.X) / 2);
        Rect1L.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
        Rect1R.Y = (Rect1LT.Y + Rect1LB.Y) / 2;
        Rect1B.X = ((Rect1LT.X + Rect1RB.X) / 2);

        if (Rect1LT.X > Rect1RT.X)
        {
            Rect_TEMP1 = Rect1RT;
            Rect_TEMP2 = Rect1R;
            Rect_TEMP3 = Rect1RB;
            Rect1RT = Rect1LT;
            Rect1R = Rect1L;
            Rect1RB = Rect1LB;
            Rect1LT = Rect_TEMP1;
            Rect1L = Rect_TEMP2;
            Rect1LB = Rect_TEMP3;

        }
        if (Rect1LT.Y > Rect1LB.Y)
        {
            Rect_TEMP4 = Rect1LB;
            Rect_TEMP5 = Rect1B;
            Rect_TEMP6 = Rect1RB;
            Rect1LB = Rect1LT;
            Rect1B = Rect1T;
            Rect1RB = Rect1RT;
            Rect1LT = Rect_TEMP4;
            Rect1T = Rect_TEMP5;
            Rect1RT = Rect_TEMP6;
        }
        this.DoubleBuffered= true;
        this.SetStyle(ControlStyles.UserPaint |
      ControlStyles.AllPaintingInWmPaint |
      ControlStyles.ResizeRedraw |
      ControlStyles.ContainerControl |
      ControlStyles.OptimizedDoubleBuffer |
      ControlStyles.SupportsTransparentBackColor
      , true);

        panel1.Invalidate();
        //public void Invalidate(Rectangle);
        //panel1.Update();
        //panel1.Refresh();
        //panel1.Invalidate(Rect1T);
        //invalidateRect(Rect_TEMP1);
        //panel1.Invalidate(Rect_TEMP1);
        //panel1.Invalidate(Rect_TEMP2);
        //panel1.Invalidate(Rect_TEMP3);
        //panel1.Invalidate(Rect_TEMP4);
        //panel1.Invalidate(Rect_TEMP5);
        //panel1.Invalidate(Rect_TEMP6);
        //panel1.Invalidate(Rect1);
        //panel1.Invalidate(Rect1B);
        //Invalidate(Rect1L, true);
        //Invalidate(Rect_TEMP1,true);

        //panel1.Invalidate(Rect1LB);
        //panel1.Invalidate(Rect1LT);
        //panel1.Invalidate(Rect1R);
        //panel1.Invalidate(Rect1RB);
        //panel1.Invalidate(Rect1T);
        //panel1.Invalidate(Rect1RT);

        //panel1.Invalidate(Rect);
    }

    if (e.Location.X >= Rect1LT.X & e.Location.Y >= Rect1LT.Y & e.Location.X <= (Rect1LT.X + 10) & e.Location.Y <= (Rect1LT.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
    }
    else if (e.Location.X >= Rect1RT.X & e.Location.Y >= Rect1RT.Y & e.Location.X <= (Rect1RT.X + 10) & e.Location.Y <= (Rect1RT.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeNESW;
    }
    else if (e.Location.X >= Rect1LB.X & e.Location.Y >= Rect1LB.Y & e.Location.X <= (Rect1LB.X + 10) & e.Location.Y <= (Rect1LB.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeNESW;
    }
    else if (e.Location.X >= Rect1RB.X & e.Location.Y >= Rect1RB.Y & e.Location.X <= (Rect1RB.X + 10) & e.Location.Y <= (Rect1RB.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
    }
    else if (e.Location.X >= Rect1B.X & e.Location.Y >= Rect1B.Y & e.Location.X <= (Rect1B.X + 10) & e.Location.Y <= (Rect1B.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeNS;
    }
    else if (e.Location.X >= Rect1R.X & e.Location.Y >= Rect1R.Y & e.Location.X <= (Rect1R.X + 10) & e.Location.Y <= (Rect1R.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeWE;
    }
    else if (e.Location.X >= Rect1T.X & e.Location.Y >= Rect1T.Y & e.Location.X <= (Rect1T.X + 10) & e.Location.Y <= (Rect1T.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeNS;
    }
    else if (e.Location.X >= Rect1L.X & e.Location.Y >= Rect1L.Y & e.Location.X <= (Rect1L.X + 10) & e.Location.Y <= (Rect1L.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeWE;
    }
    else if (e.Location.X >= (Rect1LT.X + 10) & e.Location.Y >= (Rect1LT.Y + 10) & e.Location.X <= (Rect1RB.X + 10) & e.Location.Y <= (Rect1RB.Y + 10))
    {
        this.panel1.Cursor = System.Windows.Forms.Cursors.SizeAll;
    }
}

    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
        flg1_LB = false;
        flg1_LT = false;
        flg1_RB = false;
        flg1_RT = false;
        temp1X = 0;
        temp1Y = 0;
        flg1_B = false;
        flg1_L = false;
        flg1_R = false;
        flg1_T = false;
        flg1_mid = false;
    }
}

如上所示,我正在绘制矩形,它会导致面板闪烁? 我还将Double Buffered Property设置为true,但结果仍为零。 我在面板中设置了背景图像,并且图像属性设置为拉伸,如果图像属性是图块,它不会闪烁。 我应该做些什么改变以避免闪烁。

1 个答案:

答案 0 :(得分:0)

设置DoubleBuffered属性不会阻止任何闪烁。 此属性仅允许一次渲染绘制的曲面,而不是尝试逐步直接渲染它,首先将所有图形绘制到缓冲区中。然后将其交换到要绘制的有效表面。这对你来说是透明的,但仅此而已。

如果仍然有闪烁,则表示您可能无法正确访问要绘制的曲面 在程序上驱动图形操作有两种主要方式:

  • 事件消息队列
  • 游戏循环

事件消息队列主要用于在用户或系统触发的操作上更新图形时。鼠标单击,系统通知,按下键盘键,... 这是事件驱动的,等待新事件是阻塞操作。因此,在每个事件之间可能有足够的时间处理cpu以执行其他操作。这表示如果你的事件的速度低于绘制到表面所需的时间,你可以执行一些图形操作而不会有太多的性能命中(因此会闪烁)。

while (!exit)
{
    var msg = WaitForMessage(); // Blocks until message arrives
    switch (msg.Type)
    {
        case Message.MouseMove: OnMouseMove(msg); break;
        case Message.Paint: OnPaint(msg); break;
        ...
    }
}

来源:opentk

当您需要连续绘制到图形表面和/或在没有用户交互的情况下更新图形时,游戏循环是一种更好的方法。

while (!exit)
{
    var time = GetTime();
    Update(time);
    Render(time);
}

来源:opentk

使用这种方法,您可以执行非阻塞操作,因此必须处理其他应用程序的免费CPU时间,否则您将占用100%的CPU时间。 这是FPS控制的基础。

您的代码正在使用第一种方法,因为在每次鼠标移动事件后,您使绘制的曲面无效并请求图形更新。

这不是一个好方法,因为与执行绘图所需的时间相比,鼠标移动事件可能会更快。这可能会降低用户界面的响应速度。

您可以考虑以下几点:

  • 减少图片更新所需的时间:
    • 避免在绘制操作中对堆上的新对象进行系统实例化。尝试重用固定实例。设置一次使用的样式和颜色。没有必要一遍又一遍地重复它。
  • 断开鼠标移动与图形失效之间的联系:
    • 尝试创建游戏循环,其中无效调用将以众所周知的速率执行,与鼠标移动事件无关。这将使您可以控制FPS。
  • 仅使需要失效的内容无效:
    • 您可以通过仅重新绘制需要的内容来获得性能 Invalidate方法作为重载接受一个矩形,该矩形描述将在paint方法上重绘的区域。这样可以避免重新绘制不会更改的像素。

所有这些操作都会提高性能并减少闪烁效应。