2013-12-14 99 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