2016-10-20 42 views
0

我有一個奇怪的問題。我做了我自己的用戶控制從UserControl派生。我覆蓋OnPaint。現在我在OnPaint中畫一些東西。我們假設在位置0,0。base.OnPaint訂單更改繪圖位置

如果我在自定義繪圖後打電話base.OnPaint一切都很好。但如果我在繪製東西之前調用base.OnPaint,它似乎忽略包含控件,並且該位置與表單相對,而不是相對於父控件的客戶區域。因此,當我在位置(0,0)繪製時,它將有效地繪製在負x和y上,而我只能看到它的一部分。 base.OnPaintUserControl.OnPaint。所以我不會在那裏給我的代碼打電話。

下面是一個例子:

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    var rect = new System.Drawing.Rectangle(this.ClientSize.Width - 16, 
      this.ClientSize.Height - 16, 16, 16); 

    e.Graphics.FillRectangle(new System.Drawing.SolidBrush(System.Drawing.Color.Red), rect); 

    //base.OnPaint(e); 
} 

在這種情況下,地方的客戶區域內,但不顯示在右下角的紅色矩形。如果我取消註釋最後一行並註釋第一行,則紅色矩形將按預期顯示在右下角。

我不明白。我做了很多次,並且一直工作。所以我試圖找到任何差異。唯一我發現的是,我沒有在設計師中添加我的控制器,而是將其以編程方式添加到另一個控件theContainingControl.Controls.Add(myMessedUpControl);

這也發生在我添加的每個父母 - 子女級別上。因此,如果我創建另一個控件(另一個類)並覆蓋OnPaint,那麼如果將其添加到另一個用戶控件,行爲也是相同的。

有沒有人有過這種行爲?我怎樣才能解決這個問題?問題是我想先致電base.OnPaint,也是所有人都提出這個建議。但正如我所說,我不能沒有搞亂座標。

一個注意事項:調試器中的座標確實是0,0,如DrawLine,DrawImageDrawString。但結果顯示在負座標處(相對於客戶區域)。它看起來像客戶端座標被解釋爲窗體的客戶端座標。但我不知道爲什麼。

發現問題

在我的項目有是連接Paint事件處理在我的形式的所有控件(整個層次)的圖形覆蓋類。在這個處理程序中執行轉換。這種圖形疊加讓我無數次失眠。我想我會刪除它。

+0

只有刷子和整數的FillRectangle? –

+1

'FillRectangle(brush,16)'? 16'怎麼可能是一個矩形? –

+0

抱歉粘貼錯誤的代碼。更新。 –

回答

1

Graphics對象有很多可變狀態。如果您陷入這種可變狀態,則操作順序很重要 - 例如,您可以使用Transform矩陣更改表面上渲染的所有內容的偏移量。

這聽起來像是你的方向改變了它自己的OnPaint處理程序中的一個,而沒有將其重置。在開始自己的繪畫之前,嘗試做一個e.Graphics.ResetTransform();。確保所有其他狀態也是你想要的方式(剪輯,DPI,...)。

+0

'ResetTransform'完成了這個訣竅。我只是不明白圖形對象改變的地方。它必須發生在paint事件之外,因爲我只調用了'UserControl.OnPaint'。我也沒有做任何改變。我自己的代碼中唯一的東西是繪製調用。我敢打賭,這與我經常修改的「Control.Region」有關(但在繪畫事件之外)。 –

+0

此外,繪圖在設計師的作品。轉換隻會在運行時混亂。所以我認爲在某些事件中'Control.Region'的確是變化的。 –

+0

@RoberS。那麼,Windows的整個窗口模型是非常複雜的。如果你想真正理解發生了什麼,恐怕沒有捷徑,只能瞭解窗口模型是如何工作的 - WM_PAINT和其他繪畫事件,GDI,曲面,組合等等的所有細節。另外,請注意底座'Control'上的'OnPaint'處理程序將調用'Paint'事件處理程序 - 您確定沒有?該部分也不在設計人員中執行。 – Luaan