it-swarm-vi.com

Làm thế nào để tăng gấp đôi bộ điều khiển .NET trên một biểu mẫu?

Làm cách nào tôi có thể đặt thuộc tính DoubleBuffered được bảo vệ của các điều khiển trên một biểu mẫu đang bị nhấp nháy?

47
Ian Boyd

Đây là phiên bản chung hơn của Giải pháp của Dummy .

Chúng ta có thể sử dụng sự phản chiếu để có được thuộc tính được bảo vệ DoubleBuffered , và sau đó nó có thể được đặt thành true .

Lưu ý : Bạn nên trả thuế nhà phát triển của bạn và không sử dụng bộ đệm đôi nếu người dùng đang chạy trong một phiên dịch vụ đầu cuối (ví dụ: Remote Desktop) Phương thức trợ giúp này sẽ không bật bộ đệm đôi nếu người đó đang chạy trong máy tính từ xa.

public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
   //Taxes: Remote Desktop Connection and painting
   //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
   if (System.Windows.Forms.SystemInformation.TerminalServerSession)
      return;

   System.Reflection.PropertyInfo aProp = 
         typeof(System.Windows.Forms.Control).GetProperty(
               "DoubleBuffered", 
               System.Reflection.BindingFlags.NonPublic | 
               System.Reflection.BindingFlags.Instance);

   aProp.SetValue(c, true, null); 
}
85
Ian Boyd

Kiểm tra chủ đề này

Lặp lại cốt lõi của câu trả lời đó, bạn có thể bật cờ kiểu WS_EX_COMPOSITED trên cửa sổ để lấy cả biểu mẫu và tất cả các điều khiển của nó được đệm đôi. Cờ kiểu có sẵn kể từ XP. Nó không làm cho bức tranh nhanh hơn nhưng toàn bộ cửa sổ được vẽ trong một bộ đệm ngoài màn hình và được đưa vào màn hình trong một cú đánh. Làm cho nó nhìn ngay lập tức vào mắt người dùng mà không cần nhìn thấy các đồ tạo tác. Nó không hoàn toàn không có rắc rối, một số trình kết xuất kiểu trực quan có thể bị trục trặc trên nó, đặc biệt là TabControl khi nó có quá nhiều tab. YMMV.

Dán mã này vào lớp biểu mẫu của bạn:

protected override CreateParams CreateParams {
    get {
        var cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;    // Turn on WS_EX_COMPOSITED
        return cp;
    } 
}

Sự khác biệt lớn giữa kỹ thuật này và hỗ trợ bộ đệm đôi của Winform là phiên bản của Winform chỉ hoạt động trên một điều khiển tại một thời điểm. Bạn vẫn sẽ thấy mỗi điều khiển Paint riêng lẻ. Cũng có thể trông giống như hiệu ứng nhấp nháy, đặc biệt nếu hình chữ nhật điều khiển không được tô màu tương phản xấu với nền của cửa sổ.

65
Hans Passant
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
    .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);

Ian có thêm một số thông tin về việc sử dụng điều này trên máy chủ đầu cuối.

18
dummy
public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}
12
Arno

Một cách là mở rộng điều khiển cụ thể mà bạn muốn nhân đôi bộ đệm và đặt thuộc tính DoubleBuffered bên trong ctor của điều khiển.

Ví dụ:

class Foo : Panel
{
    public Foo() { DoubleBuffered = true; }
}
8
Jeff Hubbard

Phương thức mở rộng để bật hoặc tắt bộ đệm đôi cho các điều khiển

public static class ControlExtentions
{
    /// <summary>
    /// Turn on or off control double buffering (Dirty hack!)
    /// </summary>
    /// <param name="control">Control to operate</param>
    /// <param name="setting">true to turn on double buffering</param>
    public static void MakeDoubleBuffered(this Control control, bool setting)
    {
        Type controlType = control.GetType();
        PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
        pi.SetValue(control, setting, null);
    }
}

Cách sử dụng (ví dụ: cách tạo DataGridView DoubleBuffered):

DataGridView _grid = new DataGridView();
//  ...
_grid.MakeDoubleBuffered(true);
5
MajesticRa

nobugz nhận được tín dụng cho phương thức trong liên kết của anh ấy, tôi chỉ đăng lại. Thêm ghi đè này vào Biểu mẫu:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

Điều này làm việc tốt nhất với tôi, trên Windows 7 tôi đã xuất hiện các khối lớn màu đen khi tôi thay đổi kích thước một dạng nặng điều khiển. Kiểm soát bây giờ bị trả lại thay vì! Nhưng nó tốt hơn.

5
Chris S

Trước khi bạn thử đệm đôi, hãy xem SuspendLayout ()/ResumeLayout () giải quyết vấn đề của bạn.

4
Joel Coehoorn

Điều này gây cho tôi một rất nhiề đau buồn trong hai ngày với sự kiểm soát của bên thứ ba cho đến khi tôi theo dõi nó.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

Gần đây tôi đã có rất nhiều lỗ hổng (phân nhỏ) khi định cỡ lại/vẽ lại một điều khiển có chứa một số điều khiển khác.

Tôi đã thử WS_EX_COMPOSITED và WM_SETREDRAW nhưng không có gì hoạt động cho đến khi tôi sử dụng điều này:

private void myPanel_SizeChanged(object sender, EventArgs e)
{
     Application.DoEvents();
}

Chỉ muốn vượt qua nó.

4
dnennis

phiên bản vb.net của giải pháp tốt này ....:

Protected Overrides ReadOnly Property CreateParams() As CreateParams
    Get
        Dim cp As CreateParams = MyBase.CreateParams
        cp.ExStyle = cp.ExStyle Or &H2000000
        Return cp
    End Get
End Property
2
Flip70

Bạn cũng có thể kế thừa các điều khiển vào các lớp của riêng bạn và đặt thuộc tính trong đó. Phương pháp này cũng tốt nếu bạn có xu hướng thực hiện nhiều thiết lập giống nhau trên tất cả các điều khiển.

1
MagicKat

Tôi đã thấy rằng chỉ cần thiết lập cài đặt DoubleBuffered trên biểu mẫu sẽ tự động đặt tất cả các thuộc tính được liệt kê ở đây.

0
ljs