Nó không phải là loại nhấp nháy mà bộ đệm đôi có thể giải quyết. Cũng không phải BeginUpdate hoặc SuspendLayout. Bạn có quá nhiều điều khiển, BackgroundImage có thể làm cho điều này trở nên tồi tệ hơn lot.
Bắt đầu khi UserControl tự sơn. Nó vẽ BackgroundImage, để lại các lỗ nơi cửa sổ điều khiển con đi. Mỗi đứa trẻ kiểm soát sau đó nhận được một tin nhắn để vẽ chính nó, họ sẽ điền vào các lỗ với nội dung cửa sổ của họ. Khi bạn có rất nhiều điều khiển, các lỗ đó sẽ hiển thị cho người dùng trong một thời gian. Chúng thường có màu trắng, tương phản với BackgroundImage khi trời tối. Hoặc chúng có thể là màu đen nếu biểu mẫu có thuộc tính Opacity hoặc TransparencyKey, tương phản với bất kỳ thứ gì.
Đây là một hạn chế khá cơ bản của Windows Forms, nó bị mắc kẹt với cách Windows hiển thị cửa sổ. Được sửa bởi WPF btw, nó không sử dụng các cửa sổ cho các điều khiển con. Những gì bạn muốn là tăng gấp đôi đệm toàn bộ biểu mẫu, bao gồm cả các điều khiển con. Có thể, hãy kiểm tra mã của tôi theo số this thread để biết giải pháp. Nó có tác dụng phụ mặc dù, và không thực sự tăng tốc độ vẽ. Mã này rất đơn giản, dán này trong mẫu của bạn (không phải là kiểm soát người sử dụng):
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Có rất nhiều điều bạn có thể làm để cải thiện tốc độ hội họa, đến nỗi các nhấp nháy là không đáng chú ý nữa. Bắt đầu bằng cách giải quyết BackgroundImage. Chúng có thể là thực sự là tốn kém khi hình ảnh nguồn lớn và cần được thu nhỏ để vừa với điều khiển. Thay đổi thuộc tính BackgroundImageLayout thành "Ngói". Nếu điều đó cho tốc độ đáng chú ý, hãy quay lại chương trình vẽ và thay đổi kích thước hình ảnh để phù hợp hơn với kích thước điều khiển điển hình.Hoặc viết mã trong phương thức OnResize() của UC để tạo ra một bản sao có kích thước đúng của hình ảnh sao cho nó không phải được thay đổi kích cỡ mỗi khi điều khiển được sơn lại. Sử dụng định dạng pixel Format32bppPArgb cho bản sao đó, nó hiển thị nhanh hơn khoảng 10 lần so với bất kỳ định dạng pixel nào khác.
Điều tiếp theo bạn có thể làm là ngăn không cho các lỗ này trở nên dễ thấy và tương phản xấu với hình ảnh. Bạn có thể turn off cờ kiểu WS_CLIPCHILDREN cho UC, cờ ngăn không cho UC vẽ tranh trong khu vực nơi điều khiển con đi. Dán mã này vào mã của UserControl:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
Giờ đây, điều khiển con sẽ tự vẽ trên nền của hình nền. Bạn có thể vẫn thấy chúng tự vẽ từng cái một, nhưng lỗ đen hoặc trắng trung gian xấu xí sẽ không thể nhìn thấy được.
Cuối cùng nhưng không kém phần quan trọng, giảm số lượng điều khiển con luôn là cách tiếp cận tốt để giải quyết các vấn đề về sơn chậm. Ghi đè lên sự kiện OnPaint() của UC và vẽ những gì được hiển thị trong một đứa trẻ. Nhãn đặc biệt và PictureBox là rất lãng phí. Thuận tiện cho điểm và nhấp chuột nhưng thay thế trọng lượng nhẹ của chúng (vẽ một chuỗi hoặc một hình ảnh) chỉ mất một dòng mã trong phương thức OnPaint() của bạn.
Đâu là các báo cáo này? Lý tưởng nhất, đặt chúng vào hàm tạo. Bạn có gọi là 'UpdateStyles' sau khi thiết lập những cái này không? Đó là tài liệu xấu, nhưng đôi khi có thể là cần thiết. – Thomas