2013-12-14 31 views
0

我一個看似唯一的問題所困擾......我有兩個屬性(其中包括)自定義控件稱爲邊境邊框寬度。我注意到,設置這些值會影響控件的ClientRectangle的值。的WinForms控制自定義邊框和邊框寬度影響ClientRectangle

據我所知,WinForms控件沒有「Border」和「BorderWidth」屬性,所以我不能無意中設置任何可能導致此問題的基本屬性。這裏是問題...我有以下特性:

/// <summary> 
/// Whether or not this control has a border 
/// </summary> 
[Browsable(true)] 
public bool Border { 
    get { 
    return _border; 
    } 
    set { 
    _border = value; 
    this.Invalidate(); 
    } 
} 

/// <summary> 
/// The width (in pixels) of the controls border 
/// </summary> 
[Browsable(true)] 
public int BorderWidth { 
    get { 
    return _borderWidth; 
    } 
    set { 
    if (value <= 1) value = 1; 
     _borderWidth = value; 
    } 
    } 
} 

我已經把斷點在上面和儘快無論是在_border = value_borderWidth = value線執行的this.ClientRectangle立即改變的值設置器。就好像這些屬性的值正在被.Net Framework讀取並用於調整this.ClientRectaangle。我沒有任何代碼可以做到這一點,而且我也不能,因爲ClientRectangle只是只讀的。

運行前行_border = value(設定值設定爲 「真」)

Border = false 
BorderWidth = 1 
this.ClientRectangle = {X=0 Y=0 Width=150 Height=29} 

Border = true 
BorderWidth = 1 
this.ClientRectangle = {X=1 Y=1 Width=148 Height=27} 

之前運行_borderWidth = value(其值設置爲 「2」 )

Border = true 
BorderWidth = 1 
this.ClientRectangle = {X=1 Y=1 Width=148 Height=27} 

Border = true 
BorderWidth = 2 
this.ClientRectangle = {X=2 Y=2 Width=146 Height=25} 

我不明白這是怎麼可能的,因爲我使用this.ClientRectangle Paint事件來繪製邊界和其他的東西,我結束了在更小的空間繪圖比控制的實際大小;特別是邊境不被下面的代碼繪製控件的邊緣:

private void DrawBorder(Graphics g, Rectangle r) { 
    if (Border) { 
     ControlPaint.DrawBorder(g, ClientRectangle, BorderColor, BorderWidth, ButtonBorderStyle.Solid, 
      BorderColor, BorderWidth, ButtonBorderStyle.Solid, 
      BorderColor, BorderWidth, ButtonBorderStyle.Solid, 
      BorderColor, BorderWidth, ButtonBorderStyle.Solid); 
     //float halfBorder = (float)BorderWidth/2; 
     //RectangleF r2 = new RectangleF(halfBorder, halfBorder, (float)r.Size.Width - halfBorder, (float)r.Size.Height - halfBorder); 
     //g.DrawRectangles(new Pen(BorderColor, BorderWidth), new RectangleF[] { r2 }); 
    } 
} 

道歉長的帖子,只是想提供儘可能多的信息,可以提高得到的解決方案的機會。

謝謝大家。

回答

0

這是一個真正的邊境行爲方式。我的水晶球說你已經開始用你下載的代碼控制你的控制,並且它實現了一個真實的邊界。

尋找WndProc()的覆蓋。 Windows會發送WM_NCCALCSIZE消息來要求窗口指定其邊框。併發送WM_NCPAINT來要求窗口繪製它們。您需要充分利用這些消息,並將您的繪畫代碼移至現有的WM_NCPAINT接收代碼時。或者完全刪除該代碼,以便您可以使用OnPaintBackground來繪製自定義邊框。您通常還需要打開ControlStyles.ResizeRedraw樣式標記,以防止控件在調整大小(例如,錨定在所有四面)時出現「拖尾」現象。

+0

感謝漢斯,你的水晶球部分正確。我有一個WndProc()覆蓋在其他地方開始生活。但是它沒有響應'WM_NCCALCSIZE'消息的代碼。我所做的,面對面的時間,是我自己重寫的ClientRectangle,我寫了自己(沒有剪切和粘貼),但完全忘記了!衛生署!我的ClientRectangle屬性根據_border和_borderWidth重新計算X,Y,寬度和高度,以提供上述** true **邊框行爲。 – oak

+0

我將其標記爲正確的答案,因爲它最接近幫助我追蹤我自己的失禮。 – oak

+0

也許在我給出的「真實邊框」細節中有一小塊金塊,但如果刪除問題可能更合適。 –

0

當繪製矩形與一些線寬,我們有3種尺寸,外部尺寸等於該ClientRectangle尺寸和內側尺寸比ClientRectangle寬度比高度ClientRectangle更寬2*lineWidth更少和2*lineWidth少更高。最後尺寸是中間/中間尺寸,其寬度爲lineWidth,寬度比寬度ClientRectangle寬度小,高度爲lineWidth,高度低於ClientRectangle高度。你可以計算與ControlPaint.DrawBorder作爲繼確切Rectangle

var rect = ClientRectangle; 
rect.Width -= borderWidth; 
rect.Height -= borderWidth; 
rect.Offset(borderWidth/2, borderWidth/2); 
//then use the rect instead of the ClientRectangle 
//in your ControlPaint.DrawBorder 
ControlPaint.DrawBorder(g, rect, .... 
+0

謝謝。這對於正確繪製邊框非常有用,但我仍然需要了解在設置自定義屬性時爲什麼/如何「自動」更新ClientRectangle; 「你不明白的會轉過身來咬你」:-)。 – oak