Nhìn vào dự án bạn đã đăng, nhấp nháy thực sự tồi khi bạn chọn tab đầu tiên, với các hộp nhóm được tô màu. Với tab thứ hai hoặc thứ ba hiển thị, hầu như không có bất kỳ nhấp nháy nào.

Vì vậy, rõ ràng các vấn đề có cái gì để làm với các điều khiển bạn đang hiển thị trên trang tab. Xem nhanh mã cho lớp hộp nhóm điền gradient tùy chỉnh cho biết nguyên nhân cụ thể hơn. Bạn đang thực hiện lot của quá trình xử lý thực sự tốn kém mỗi khi bạn vẽ một trong các điều khiển hộp nhóm. Bởi vì mỗi kiểm soát hộp nhóm phải tự sơn lại mỗi lần biểu mẫu được thay đổi kích thước, mã đó sẽ được thực thi một số lần không thể tin được.
Cộng với, bạn có nền điều khiển được đặt thành "Trong suốt", được đặt trong WinForms bằng cách yêu cầu cửa sổ chính vẽ đầu tiên bên trong cửa sổ điều khiển để tạo pixel nền. Sự kiểm soát sau đó tự vẽ lên trên đó. Đây cũng là công việc nhiều hơn điền vào nền điều khiển với một màu rắn như SystemColors.Control
, và nó gây ra cho bạn để xem các điểm ảnh của biểu mẫu được rút ra trong khi bạn thay đổi kích thước hình thức, trước khi các hộp nhóm có cơ hội để vẽ mình.
Dưới đây là các mã cụ thể tôi đang nói về từ tùy chỉnh lớp kiểm soát GroupBox gradient điền của bạn:
protected override void OnPaint(PaintEventArgs e)
{
if (Visible)
{
Graphics gr = e.Graphics;
Rectangle clipRectangle = new Rectangle(new Point(0, 0), this.Size);
Size tSize = TextRenderer.MeasureText(Text, this.Font);
Rectangle r1 = new Rectangle(0, (tSize.Height/2), Width - 2, Height - tSize.Height/2 - 2);
Rectangle r2 = new Rectangle(0, 0, Width, Height);
Rectangle textRect = new Rectangle(6, 0, tSize.Width, tSize.Height);
GraphicsPath gp = new GraphicsPath();
gp.AddRectangle(r2);
gp.AddRectangle(r1);
gp.FillMode = FillMode.Alternate;
gr.FillRectangle(new SolidBrush(Parent.BackColor), clipRectangle);
LinearGradientBrush gradBrush;
gradBrush = new LinearGradientBrush(clipRectangle, SystemColors.GradientInactiveCaption, SystemColors.InactiveCaptionText, LinearGradientMode.BackwardDiagonal);
gr.FillPath(gradBrush, RoundedRectangle.Create(r1, 7));
Pen borderPen = new Pen(BorderColor);
gr.DrawPath(borderPen, RoundedRectangle.Create(r1, 7));
gr.FillRectangle(gradBrush, textRect);
gr.DrawRectangle(borderPen, textRect);
gr.DrawString(Text, base.Font, new SolidBrush(ForeColor), 6, 0);
}
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
if (this.BackColor == Color.Transparent)
base.OnPaintBackground(pevent);
}
Và bây giờ mà bạn đã nhìn thấy mã, cờ cảnh báo đỏ phải đi lên. Bạn đang tạo một nhóm của các đối tượng GDI + (bàn chải, bút mực, vùng, v.v.), nhưng không thành Dispose
bất kỳ đối tượng nào trong số chúng! Hầu hết tất cả mã đó phải được bao bọc trong các câu hỏi using
. Đó chỉ là mã hóa cẩu thả.
Làm tất cả công việc đó tốn một cái gì đó.Khi máy tính bị buộc phải dành rất nhiều thời gian để điều khiển hiển thị, những thứ khác tụt lại phía sau. Bạn thấy một nhấp nháy vì nó căng để theo kịp với thay đổi kích thước. Nó không khác gì so với bất cứ thứ gì khác làm quá tải máy tính (như tính toán giá trị của pi), nó thực sự dễ dàng để làm như vậy khi bạn sử dụng nhiều điều khiển được vẽ tùy chỉnh như bạn làm ở đây. Minh bạch là khó khăn trong Win32, và như vậy là rất nhiều bức tranh 3D tùy chỉnh. Nó làm cho giao diện người dùng trông và cảm thấy bối rối với người dùng. Tuy nhiên, một lý do khác mà tôi không hiểu sự vội vã đi từ kiểm soát bản địa.
Bạn thực sự chỉ có ba lựa chọn:
- Deal với nhấp nháy. (Tôi đồng ý, đây không phải là một lựa chọn tốt.)
- Sử dụng các điều khiển khác nhau, như các tiêu chuẩn được tích hợp sẵn. Chắc chắn, họ có thể không có một hiệu ứng gradient ưa thích, nhưng đó sẽ xem xét một nửa thời gian bị hỏng nếu người dùng đã tùy chỉnh chủ đề Windows của họ. Cũng rất khó đọc văn bản màu đen trên nền xám đậm.
- Thay đổi mã vẽ trong các điều khiển tùy chỉnh của bạn để thực hiện ít công việc hơn. Bạn có thể nhận được bằng một số "tối ưu hóa" đơn giản mà không làm bạn mất bất kỳ hiệu ứng hình ảnh nào, nhưng tôi nghi ngờ điều này là không thể. Đó là một sự cân bằng giữa tốc độ và kẹo mắt. Không làm gì luôn nhanh hơn.
Nếu tôi không bỏ phiếu, tôi sẽ bỏ phiếu để đóng câu hỏi này là bản sao của câu hỏi này: [Winforms Double Buffering] (http://stackoverflow.com/questions/3718380/winforms-double -buffering). Vì vậy, ở đây nó là miễn phí. –
@Cody Gray - Tôi không đồng ý! Câu hỏi có thể tương tự, nhưng câu trả lời được cung cấp theo liên kết bạn gửi là hoàn toàn sai/xấu vì nó gây ra rất nhiều tác dụng phụ. – HABJAN
@HABJAN: Bạn có thể cho tôi biết về một số tác dụng phụ đó không? –