簡體   English   中英

在控件周圍繪制邊框

[英]Drawing border around control

好吧,我想在面板控件周圍繪制自定義邊框,我發現可以使用以下控件輕松實現

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);

但是,此方法和我嘗試過的所有其他方法實際上是在面板內部繪制邊框,因此當我將某些控件停靠在面板內部時,該控件會隱藏邊框。

在此處輸入圖片說明

所以我想知道是否有一種方法可以在控件外部繪制邊框來避免此問題?

有幾種解決方案,但是我認為這是最簡單的解決方案,您必須確保將面板放置在另一個容器上,該容器為其外部邊界留出足夠的空間。

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();
   }
}

請注意,邊框繪制代碼現在必須在面板的父面板上繪制,您必須相應地調整邊框Rectangle(當然,它比在面板內部繪制的邊框大)。

另請注意,由於在父板上進行繪制,因此當更改面板的大小或位置時,我們需要使父板無效才能正確重繪。 Invalidate()方法可以接受一個Rectangle來使該矩形無效,您可以計算要繪制的邊框Rectangle ,還可以傳入該Invalidate方法來提高繪制性能(主要有助於防止閃爍)。

在面板控件上有一個BorderStyle屬性。 盡管您的選擇受到限制。

丟失繪圖邊框的原因是,繪圖位於面板空間內。

您有兩種選擇來獲得想要的東西。

1)獲得所需的最簡單的方法是堆疊面板。 背面的顏色要與邊框的背景顏色相同。 然后,將另一個面板放置在該面板內,並使其邊框具有您想要的邊框寬度。 (如果要在所有側面上使用4像素邊框,則“內部” /“頂部”面板的寬度和高度將減小8像素)。

2)向Panel對象添加功能以按需繪制邊框。 但這將是很多工作。

骯臟又容易解決。 基於小磷蝦和國王金的答案。

您可以創建自己的Panel ,它將在內部容納另一個Panel (在構造函數中創建它),並將所有ControlAdded / ControlRemoved轉發給它,同時將其完美地放置在內部。 這樣,您可以像現在一樣保持繪制邊框。

除了可以在您的區域之外進行繪畫之外,還可以使用丑陋的解決方法,而可以將事物保留在邊界內。 所以不要使用停靠,使用錨。

例如:

Controls.Add(mScrollBar);
int borderSize = 1; // some border size

mScrollBar.SetBounds(
   Right - mScrollBar.Width - borderSize, // x; from the right, the width and the border
   borderSize,                            // y; from the top, just the border
   mScrollBar.Width,                      // width can stay the same
   Height - borderSize * 2                // height minus two borders
);

mScrollBar.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM