好吧,我想在面板控件周围绘制自定义边框,我发现可以使用以下命令轻松实现
ControlPaint.DrawBorder(e.Graphics, ClientRectangle,
Color.Indigo, 10, ButtonBorderStyle.Solid,
Color.Indigo, 10, ButtonBorderStyle.Solid,
Color.Indigo, 10, ButtonBorderStyle.Solid,
Color.Indigo, 10, ButtonBorderStyle.Solid);
Run Code Online (Sandbox Code Playgroud)
但是,此方法和我尝试过的所有其他方法实际上在面板内绘制边框,因此当我将某些控件停靠在其中时,该控件会隐藏边框。

所以我想知道有没有办法在控件之外绘制边框来避免这个问题?
有几种解决方案,但我认为这是最简单的解决方案,您必须确保将面板放置在另一个容器上,为其外边框留出足够的空间。
public class XPanel : Panel {
public XPanel(){
BorderWidth = 5;
}
Control previousParent;
public float BorderWidth {get;set;}
protected override void OnParentChanged(EventArgs e){
base.OnParentChanged(e);
if(Parent != previousParent){
if(Parent != null) Parent.Paint += ParentPaint;
if(previousParent != null) previousParent.Paint -= ParentPaint;
previousParent = Parent;
}
}
private void ParentPaint(object sender, PaintEventArgs e){
using(Pen p = new Pen(Color.Blue, BorderWidth))
using(var gp = new GraphicsPath())
{
float halfPenWidth = BorderWidth / 2;
var borderRect = new RectangleF(Left - halfPenWidth, Top - halfPenWidth,
Width + BorderWidth, Height + BorderWidth);
gp.AddRectangle(borderRect);
e.Graphics.DrawPath(p,gp);
}
}
protected override void OnSizeChanged(EventArgs e){
base.OnSizeChanged(e);
if(Parent!=null) Parent.Invalidate();
}
protected override void OnLocationChanged(EventArgs e){
base.OnLocationChanged(e);
if(Parent != null) Parent.Invalidate();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,边框绘制代码现在必须在面板的父级上绘制,您必须相应地调整边框矩形(它当然比面板内绘制的边框大)。
另请注意,由于在父级上绘图,因此当面板的大小或位置发生更改时,我们需要使父级无效才能正确重绘。该Invalidate()方法可以接受一个Rectangle只是在该矩形上无效,您可以计算要绘制的边框矩形,并传入该Invalidate方法以稍微提高绘制的性能(主要有助于防止闪烁)。
| 归档时间: |
|
| 查看次数: |
5351 次 |
| 最近记录: |