2010-02-18 14 views
19

Tôi có mã cho phép kéo xung quanh một hình dạng không biên giới trong các biểu mẫu winform mà tôi đã sử dụng trong vài tháng nay, hoạt động rất tốt.Invalidate vs Update

Nhưng khi lần đầu tiên tôi được cung cấp mã, họ đã sử dụng this.Invalidate(); trong sự kiện MouseMove của Biểu mẫu và Biểu mẫu nhấp nháy một chút và chậm khi kéo xung quanh. Vì vậy, tôi đã thay thế Invalidate() bằng Update() trong sự kiện MouseMove và, thật ngạc nhiên, Biểu mẫu giờ đây có thể được kéo rất mượt mà và không có nhấp nháy nào.

Ai đó có thể giải thích cho tôi lý do tại sao Cập nhật làm cho mã hoạt động tốt hơn Invalidate, ngay cả khi Invalidate âm thanh giống như đó là quyền phù hợp để sử dụng?

Xin cảm ơn :)

P.S. Có lẽ nó sẽ giúp ích nhiều hơn nếu tôi thêm mã ... Thêm nó ngay bây giờ.

Sửa - Dưới đây là các mã:


private void titlebar_MouseDown(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = true; 

    this.LastCursorPosition = new Point(e.X, e.Y); 

    if (this.BackColor == Color.White) 
    { 
     this.BackColor = Color.GhostWhite; 
     tbox.BackColor = Color.GhostWhite; 
     tbox.ForeColor = Color.Black; 
    } 
    else 
    { 
     this.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.ForeColor = Color.White; 
    } 
} 

private void titlebar_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (this.IsMouseDown == true) 
    { 
     //Move the form 
     this.Location = new Point(this.Left - (this.LastCursorPosition.X - e.X), this.Top - (this.LastCursorPosition.Y - e.Y)); 

     // Update works better than Invalidate();. 
     Update(); 
    } 
} 

private void titlebar_MouseUp(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = false; 
    this.BackColor = fc; 
    tbox.BackColor = fc; 
} 

Trả lời

12

làm mất hiệu lực đánh dấu cửa sổ như cần phải được làm mới (tại một số điểm). Cập nhật làm nó ở đó và sau đó nếu tôi nhớ chính xác

Đây là một link để giải thích sự khác biệt tốt hơn tôi muốn có thể

+2

Cảm ơn một loạt Martin. :) –

31

Invalidate() đơn giản thêm một vùng trong khu vực cập nhật của điều khiển. Lần tiếp theo bạn nhận được WM_PAINT, khu vực bạn đã vô hiệu hóa cộng với bất kỳ khu vực không hợp lệ nào khác, được đánh dấu để vẽ. Khi RedrawWindow() được gọi, thông thường sẽ gửi một tin nhắn WM_PAINT đến hàng đợi ứng dụng. Hệ thống này là miễn phí để làm những gì nó muốn với điều đó, thường kinh doanh bức xúc hơn, và sơn khi nó có thể.

Nếu bạn gọi Update(), bạn bị lỗi 's UpdateWindow() GDI + trong đó sẽ không đánh dấu một khu vực cho sơn lại, nhưng đẩy một WM_PAINT trực tiếp đến WNDPROC(), bỏ qua hàng đợi ứng dụng.

Nếu bạn cần làm mới ngay lập tức kiểm soát, hãy sử dụng Refresh(), làm mất hiệu lực vùng đó ngay lập tức gọi Update().

+0

Tôi nhận ra đây là một bài đăng cũ và có lẽ điều này nên được đăng dưới dạng câu hỏi riêng, nhưng tôi không rõ ràng khi nào bạn sẽ sử dụng Cập nhật và khi nào bạn sẽ sử dụng Làm mới. Nó có vẻ như cả hai lực lượng ngay lập tức sơn lại. Bạn có thể làm rõ? Cảm ơn! –

+4

@AdamPlocher Từ phương thức nhận xét nó sẽ xuất hiện rằng 'Invalidate()' chỉ đơn giản là cờ khu vực như yêu cầu sơn, nhưng không nhất thiết phải sơn. 'Update()' buộc bất kỳ vùng nào không hợp lệ hiện hành để vẽ lại, nhưng không gắn cờ bất kỳ thứ gì. Và 'Refresh()' kết thúc tốt đẹp hai hoạt động với nhau, trước tiên gắn cờ vùng kiểm soát là không hợp lệ và sau đó ngay lập tức yêu cầu khu vực được cập nhật (được sơn lại). ** Chỉnh sửa: ** http://stackoverflow.com/a/952964/1718702 – HodlDwon

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