1. 程式人生 > >c# 窗體雙緩衝機制

c# 窗體雙緩衝機制

以下是msdn的說明:

雙緩衝使用記憶體緩衝區來解決由多重繪製操作造成的閃爍問題。 當啟用雙緩衝時,所有繪製操作首先呈現到記憶體緩衝區,而不是螢幕上的繪圖圖面。所有繪製操作完成後,記憶體緩衝區直接複製到與其關聯的繪圖圖面。因為只在螢幕上執行一項圖形操作,所以消除了與複雜繪圖操作關聯的圖形閃爍。對於大多數應用程式而言,由 .NET Framework 提供的預設雙緩衝將提供最佳結果。預設情況下,標準 Windows 窗體控制元件是雙緩衝的。可以通過兩種方法對窗體和所創作的控制元件啟用預設雙緩衝。兩種方法都將為窗體或控制元件啟用預設雙緩衝並提供無閃爍的圖形呈現。建議僅對已為其編寫所有呈現程式碼的自定義控制元件呼叫  方法。


使用窗體的雙緩衝只需要將DoubleBuffered 的屬性設定為true就可以了。

下面的程式碼是一個畫線的應用,在窗體上使用雙緩衝,窗體上畫線,不會出現閃爍,而容器內出現閃爍。

namespace line
{
    public partial class Form1 : Form
    {
        private bool ishuaxian = false;
        private bool systemhuaxian = false;
        PointClass systempointitem = new PointClass();
        List<PointClass> tt = new List<PointClass>();
        Point pointtemp;
        public Form1()
        {
            this.DoubleBuffered = true;//將窗體的 DoubleBuffered 屬性設定為 true 將使 Paint 事件中基於圖形的程式碼被雙緩衝
            //this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//通過呼叫 SetStyle 方法將 OptimizedDoubleBuffer 標誌設定為 true。
            InitializeComponent();
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (ishuaxian)
            {
                pointtemp = e.Location;
                systemhuaxian = true;
            }
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            if (ishuaxian)
            {
                systemhuaxian = false;
                PointClass pointsignal = new PointClass();
                pointsignal.pointStart = pointtemp;
                pointsignal.pointEnd = e.Location;
                systempointitem = pointsignal;
                tt.Add(pointsignal);
                //panel_deviceconnect.Refresh();
                //this.Refresh();
                this.Invalidate();
            }
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {

            Pen pen = new Pen(Color.FromArgb(255, 0, 255, 255), 2);
            pen.StartCap = LineCap.ArrowAnchor;
            pen.EndCap = LineCap.RoundAnchor;
            for (int i = 0; i < tt.Count; i++)
            {
                e.Graphics.DrawLine(pen, tt[i].pointStart.X, tt[i].pointStart.Y, tt[i].pointEnd.X, tt[i].pointEnd.Y);
            }
            e.Graphics.DrawLine(pen, systempointitem.pointStart.X, systempointitem.pointStart.Y, systempointitem.pointEnd.X, systempointitem.pointEnd.Y);


        }

        private void Form1_Load(object sender, EventArgs e)
        {
 
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (systemhuaxian)
            {
                PointClass pointsignal = new PointClass();
                pointsignal.pointStart = pointtemp;
                pointsignal.pointEnd = e.Location;
                systempointitem = pointsignal;
                //panel_deviceconnect.Refresh();
                //this.Refresh();
                this.Invalidate();
                
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ishuaxian = true;
        }

  

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (ishuaxian)
            {
                pointtemp = e.Location;
                systemhuaxian = true;
            }
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (systemhuaxian)
            {
                PointClass pointsignal = new PointClass();
                pointsignal.pointStart = pointtemp;
                pointsignal.pointEnd = e.Location;
                systempointitem = pointsignal;
                //panel_deviceconnect.Refresh();
                //this.Refresh();
                panel1.Invalidate();

            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (ishuaxian)
            {
                systemhuaxian = false;
                PointClass pointsignal = new PointClass();
                pointsignal.pointStart = pointtemp;
                pointsignal.pointEnd = e.Location;
                systempointitem = pointsignal;
                tt.Add(pointsignal);
                //panel_deviceconnect.Refresh();
                //this.Refresh();
                panel1.Invalidate();
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.FromArgb(255, 0, 255, 255), 2);
            pen.StartCap = LineCap.ArrowAnchor;
            pen.EndCap = LineCap.RoundAnchor;
            for (int i = 0; i < tt.Count; i++)
            {
                e.Graphics.DrawLine(pen, tt[i].pointStart.X, tt[i].pointStart.Y, tt[i].pointEnd.X, tt[i].pointEnd.Y);
            }
            e.Graphics.DrawLine(pen, systempointitem.pointStart.X, systempointitem.pointStart.Y, systempointitem.pointEnd.X, systempointitem.pointEnd.Y);

        }
    }
}