2017-02-12 90 views
0

我創建了繪製邊框(包含兩個矩形)的自定義面板。問題是,如果我調整窗口的大小,就會留下殘留......就像Windows XP的紙牌動畫一樣。請參閱下面的截圖。我調整了窗口的右側。當調整窗口大小時,在OnPaint()上繪製殘差

什麼是錯的,我該如何解決這個問題?

Resized window to the right

protected override void OnPaint(PaintEventArgs e) 
{ 
    var outer = ClientRectangle; 
    outer.Width -= 1; 
    outer.Height -= 1; 
    var inner = outer; 
    inner.X++; 
    inner.Y++; 
    inner.Width -= 2; 
    inner.Height -= 2; 

    e.Graphics.DrawRectangle(DarkPen, outer); 
    e.Graphics.DrawRectangle(WhitePen, inner); 

    base.OnPaint(e); 
} 

UPDATE

起初我以爲這是因爲我沒有刪除之前繪製的矩形。所以我打電話FillRectangle刪除裏面。

var contentArea = inner; 
contentArea.X++; 
contentArea.Y++; 
contentArea.Width -= 2; 
contentArea.Height -= 2; 
e.Graphics.FillRectangle(SystemBrushes.Control, contentArea); 

但它也沒有工作。看起來控制僅繪製新擴展的部分,而不繪製整個區域。

回答

4

Form類被優化爲一個容器控件。容器通常只有一個背景顏色來繪製。所以,正如你注意到的那樣,確實「只畫出新擴大的部分」。或者更準確地說,它不會覆蓋以前的像素,容易從產生的拖尾效應中識別出來。當你調整窗口大小時,Winforms設計會變得更加活潑,當表單有很多控件並且非常引人注目時,它會成爲瓶頸。

您必須將其ResizeRedraw屬性設置爲true,以便在必要時重新繪製其整個曲面。設置DoubleBuffered屬性爲true可能不會傷害繪圖代碼變得細緻,並開始注意到閃爍。

所以,大致爲:

public Form1() { 
     InitializeComponent(); 
     this.ResizeRedraw = true; 
     this.DoubleBuffered = true; 
    } 

優化的OnPaint()一般不會有回報的策略,Windows本身已經繪製反對什麼髒區片段。

+0

它的工作原理,但我只是想知道這是否是推薦的方法。我的意思是,我知道並非所有區域都需要重新繪製(在上面的更新中,我填充了整個內容區域以確保它是一個快速和骯髒的解決方案)。我可以指定需要更新的區域嗎? –

+2

您不指定區域,操作系統指定它。作爲e.ClipRectangle屬性傳遞給您。實際上使用它,呃,很難與已經使用它的操作系統競爭。好的,當繪圖對象完全落在剪切矩形之外時,您可以避免觸摸自己代碼中的大量數據。你有什麼不符合長期的資格。 –

相關問題