2012-04-28 51 views
18

Tôi đã biết rằng bằng cách thêm TreeView.BeginUpdate sẽ ngăn chặn nhấp nháy của treeview, nhưng khi tôi thêm nó vào dự án của tôi tất cả các nút của treeview của tôi biến mất, có thể bất kỳ cơ thể cho tôi biết lý do tại sao nó xảy ra, đây là đoạn mã mà tôi đã qua sử dụng TreeView.BeginUpdate và TreeView.EndUpdateNhấp nháy trong nháy mắt?

TreeNode treeNode = new TreeNode("Windows"); 
     treeView1.Nodes.Add(treeNode); 
     // 
     // Another node following the first node. 
     // 
     treeNode = new TreeNode("Linux"); 
     treeView1.Nodes.Add(treeNode); 
     // 
     // Create two child nodes and put them in an array. 
     // ... Add the third node, and specify these as its children. 
     // 
     TreeNode node2 = new TreeNode("C#"); 
     TreeNode node3 = new TreeNode("VB.NET"); 
     TreeNode[] array = new TreeNode[] { node2, node3 }; 
     // 
     // Final node. 
     // 
     treeNode = new TreeNode("Dot Net Perls", array); 
     treeView1.Nodes.Add(treeNode); 
+6

Điều đầu tiên không đúng - bạn đang làm 'BeginUpdate' /' EndUpdate' trong vòng lặp - và tệ hơn, 'EndUpdate' được lồng trong một số mã có điều kiện - tôi thường mong đợi thấy điều gì đó ngăn chặn các cập nhật trực quan được bao quanh toàn bộ các bản cập nhật (theo ví dụ thứ hai của bạn) –

+0

bất chấp mã có vấn đề, có vẻ như bạn đang cố khắc phục một triệu chứng của sự cố. Là câu hỏi thực sự tại sao bạn có được nhấp nháy ở nơi đầu tiên? hoặc không có nhấp nháy? –

+0

nếu tôi sử dụng ngay trên việc bổ sung các nút i có nghĩa là (.Nodes.Add) đó sẽ là đủ ?? – vettori

Trả lời

60

Các Begin/EndUpdate() phương pháp là không được thiết kế để loại bỏ nhấp nháy. Bắt flicker tại EndUpdate() là không thể tránh khỏi, nó repaints kiểm soát. Chúng được thiết kế để tăng tốc độ thêm một số lượng lớn các nút, điều này sẽ bị chậm theo mặc định vì mỗi mục đơn lẻ đều gây ra một lần lặp lại. Bạn đã làm cho nó tồi tệ hơn rất nhiều bằng cách đặt chúng bên trong vòng lặp for, di chuyển chúng ra bên ngoài để cải thiện ngay lập tức.

Điều đó có thể sẽ đủ để giải quyết vấn đề của bạn. Nhưng bạn có thể làm cho nó tốt hơn, triệt tiêu nhấp nháy đòi hỏi phải đệm đôi. Lớp .NET TreeView ghi đè thuộc tính DoubleBuffered và ẩn. Đó là một tai nạn lịch sử, điều khiển Windows bản địa chỉ hỗ trợ đệm đôi trong Windows XP và sau đó. .NET đã từng hỗ trợ Windows 2000 và Windows 98.

Điều đó không còn chính xác nữa trong những ngày này. Bạn có thể đặt nó trở lại bằng cách lấy ra lớp của riêng bạn từ TreeView. Thêm một lớp mới vào dự án của bạn và dán mã được hiển thị bên dưới. Biên dịch. Thả điều khiển mới từ đầu hộp công cụ lên biểu mẫu của bạn, thay thế TreeView hiện tại. Hiệu ứng này rất đáng chú ý, đặc biệt là khi cuộn.

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

class BufferedTreeView : TreeView { 
    protected override void OnHandleCreated(EventArgs e) { 
     SendMessage(this.Handle, TVM_SETEXTENDEDSTYLE, (IntPtr)TVS_EX_DOUBLEBUFFER, (IntPtr)TVS_EX_DOUBLEBUFFER); 
     base.OnHandleCreated(e); 
    } 
    // Pinvoke: 
    private const int TVM_SETEXTENDEDSTYLE = 0x1100 + 44; 
    private const int TVM_GETEXTENDEDSTYLE = 0x1100 + 45; 
    private const int TVS_EX_DOUBLEBUFFER = 0x0004; 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
} 
+5

MSDN gợi ý rằng việc bạn sử dụng TVM_SETEXTENDEDSTYLE không hoàn toàn chính xác; mỗi http://msdn.microsoft.com/en-us/library/windows/desktop/bb773744(v=vs.85).aspx WPARAM là một mặt nạ và LPARAM là cờ. Vì vậy, bỏ qua việc lấy phong cách cũ và chỉ làm SendMessage (this.Handle, TVM_SETEXTENDEDSTYLE, (IntPtr) TVS_EX_DOUBLEBUFFER, (IntPtr) TVS_EX_DOUBLEBUFFER); – EricLaw

+0

Ugh, quả thật vậy. Tôi đang sử dụng một bản sao cũ của thư viện MSDN mà tài liệu này sai. Cảm ơn cho chính xác! –

Các vấn đề liên quan