2009-06-04 34 views

Trả lời

37

Phương thức Invalidate() sẽ gây ra một lần sơn lại.

MSDN Link

4

Gọi control.invalidate và sự kiện sơn sẽ được nâng lên.

+1

private void Form1_Paint (object sender, System.Windows.Forms.PaintEventArgs e) { System.Drawing.Graphics đồ họa = this.CreateGraphics(); System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle (0, 0, 50, 50); graphics.DrawEllipse (System.Drawing.Pens.Black, rectangle); graphics.DrawRectangle (System.Drawing.Pens.Red, rectangle); } Khi nào phương pháp sơn này được gọi là để sơn lại biểu mẫu. Nó không sơn lại hình thức không phải nó. –

5

Tôi nghĩ bạn cũng có thể gọi Refresh().

+0

Cảm ơn bạn Brian. Làm việc tuyệt vời.! –

77

Trong một phương pháp Form hoặc Control của bạn, bạn có 3 lựa chọn:

this.Invalidate(); // request a delayed Repaint by the normal MessageLoop system  
this.Update();  // forces Repaint of invalidated area 
this.Refresh();  // Combines Invalidate() and Update() 

Thông thường, bạn sẽ chỉ cần gọi Invalidate() và để cho hệ thống kết hợp điều đó với bản cập nhật màn hình khác. Nếu bạn vội vàng, bạn nên gọi số Refresh() nhưng sau đó bạn có nguy cơ bị lặp lại nhiều lần vì các điều khiển khác (đặc biệt là Phụ huynh) Đang vô hiệu hóa.

Cách thông thường Windows (Win32 và WinForms.Net) xử lý việc này là đợi MessageQueue để chạy trống và sau đó xử lý tất cả các vùng màn hình bị vô hiệu. Đó là hiệu quả bởi vì khi một cái gì đó thay đổi mà thường cascades vào những thứ khác (điều khiển) thay đổi là tốt.

Kịch bản phổ biến nhất cho Update() là khi bạn thay đổi thuộc tính (ví dụ: label1.Text, sẽ làm mất hiệu lực nhãn) trong vòng lặp for và vòng lặp đó tạm thời chặn Message-Loop. Bất cứ khi nào bạn sử dụng nó, bạn nên tự hỏi mình nếu bạn không nên sử dụng một Thread thay thế. Nhưng câu trả lời là không phải lúc nào cũng có.

+8

Tôi muốn làm rõ. Update() sẽ ngay lập tức vẽ lại bất kỳ phần nào của điều khiển đã bị vô hiệu. Bạn vẫn cần phải vô hiệu hóa trước tiên. Làm mới() sẽ làm mất hiệu lực và ngay lập tức vẽ lại toàn bộ điều khiển. Khi tôi viết một điều khiển mà nó vẽ riêng, tôi gọi Invalidate() với một hình chữ nhật bẩn, sau đó gọi Update() vì lợi ích của phản ứng, và tránh xa Refresh() vì lợi ích của hiệu suất. – snarf

+0

Lưu ý rằng có thể có hiệu suất CPU lớn khác nhau tùy thuộc vào phương pháp bạn sử dụng. 'this.Invalidate()' yêu cầu ít tài nguyên CPU nhất vì bạn không ép buộc những thứ bên ngoài vòng lặp thông điệp chuẩn, và điều này đặc biệt đúng nếu bạn có thể gọi 'this.Invalidate (false)' để bạn chỉ gọi 'OnPaint () 'trên điều khiển/biểu mẫu chính và không phải là điều khiển con. Đối với một trong các UserControls của tôi, di chuyển từ 'this.Update()' sang 'this.Invalidate (false)' giảm tải CPU theo hệ số 4. –

3

Làm mới cũng có thể làm cho mã dễ đọc hơn nhiều, tùy thuộc vào ngữ cảnh.

6

Tôi đã tìm thấy Invalidate() tạo quá nhiều nhấp nháy. Đây là tình huống của tôi. Kiểm soát tùy chỉnh mà tôi đang phát triển sẽ vẽ toàn bộ nội dung của mình qua việc xử lý sự kiện Sơn.

this.Paint += this.OnPaint; 

Trình xử lý này gọi là thường trình tùy chỉnh thực tế vẽ.

private void OnPaint(object sender, PaintEventArgs e) 
{ 
    this.DrawFrame(e.Graphics); 
} 

Để mô phỏng cuộn Tôi muốn vẽ lại điều khiển của mình mỗi khi con trỏ di chuyển trong khi nhấn phím trái chuột. Lựa chọn đầu tiên của tôi là sử dụng Invalidate() như sau.

private void RedrawFrame() 
{ 
    var r = new Rectangle(
     0, 0, this.Width, this.Height); 

    this.Invalidate(r); 
    this.Update(); 
} 

Các cuộn kiểm soát OK nhưng thấp thoáng vượt xa bất kỳ mức độ thoải mái. Vì vậy, tôi quyết định thay vì vẽ lại điều khiển, hãy gọi phương thức DrawFrame() tùy chỉnh của mình trực tiếp sau khi xử lý sự kiện MouseMove. Điều đó tạo ra một cuộn trơn tru mà không nhấp nháy.

private void RedrawFrame() 
{ 
    var g = Graphics.FromHwnd(this.Handle); 
    this.DrawFrame(g); 
} 

Phương pháp này có thể không áp dụng được cho tất cả các trường hợp, nhưng cho đến nay nó vẫn phù hợp với tôi.

+0

+1 cho 'this.Invalidate (r) ' –

+1

Hãy cẩn thận, tôi nghĩ rằng kết quả từ FromHwnd() nên được Disposed một lần nữa (đặt nó trong một 'using() {}') –

+3

Sử dụng đệm đôi để thoát khỏi nhấp nháy. – TheRealChx101

0

sử dụng Control.InvokePaint bạn cũng có thể sử dụng nó để làm bằng tay đôi đệm

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