2008-11-20 80 views
5

我希望能夠創建一個黑色自定義窗口(帶有邊框和控件),就像作爲表情混合,Twirl或Adobe Lightroom的一部分提供的那樣。Winforms - 如何創建自定義窗口邊框並關閉/最小化按鈕?

是否有創建所有者繪製窗口的最佳實踐方法?

平臺:C#和WindowsForms(所有版本)

+0

這裏是使用面板創建自定義窗體表單的文章 - [使用面板在C#中創建自定義Windows窗體](http://www.codeproject.com/Articles/1068043/Creating-Custom-Windows-Forms-in -Charrp-using-Pane) – 2016-02-01 07:56:39

+0

[WinForms應用中的自定義標題欄/ chrome]的可能重複(http://stackoverflow.com/questions/42460/custom-titlebars-chrome-in-a-winforms-app) – 2016-05-21 04:56:04

回答

4

如果自定義鉻工具不能爲您提供與您想要的外觀和感覺,這種事情是很容易在C#中做自己。基本上,您可以創建一個無邊界的窗體(FormBorderStyle = None),然後通過將控件放置在需要它們的位置(標題欄的標籤,關閉和最小化的命令按鈕等)和/或繪圖來自己創建所有控件和邊框直接使用Graphics對象在表單的表面上。

您還必須實現代碼以允許表單被其「假」標題欄拖動(有關如何執行此操作的示例,請參見this answer)。您可能還必須實現自己的調整大小機制(如果需要可調整大小的表單)。

最後,儘管自定義表單代碼可能有點笨拙,但您可以在單個表單上實現它,然後讓應用程序中的所有其他表單繼承此表單,這使其成爲一種非常有用的自定義技術 - 整個應用程序的皮膚。

+0

老實說一個非常公平的方法 – 2017-03-28 16:46:27

2

我的任務是使活動窗口更明顯,明亮 - 比其他人,應用程序的非活動窗口。應用程序有很多打開的窗口,一些模式,一些無模式 - 和MDI的父窗口。

你可以使用類似not-a-border的東西 - 客戶區內的一個框架。這裏是代碼片段,基類的一部分(可以直接在一個形式使用):該類的

#region Кастомизированное поведение - рамки, активность и т.д. 
    private bool isCurrentlyActive = false; 
    private bool childControlsAreHandled = false; 
    private Pen activeWindowFramePen, inactiveWindowFramePen; 
    private Point[] framePoints; 

    private void AddControlPaintHandler(Control ctrl) 
    { 
     ctrl.Paint += DrawWindowFrame; 
     if (ctrl.Controls != null) 
     { 
      foreach (Control childControl in ctrl.Controls) 
      { 
       AddControlPaintHandler(childControl); 
      } 
     } 
    } 

    protected override void OnActivated(EventArgs e) 
    { 
     base.OnActivated(e); 
     if ((this.childControlsAreHandled == false) 
      && (WindowFrameType != Forms.WindowFrameType.NoFrame) 
      && (this.MdiParent == null)) 
     { 
      RecalculateWindowFramePoints(); 
      AddControlPaintHandler(this); 
      this.childControlsAreHandled = true; 
     } 

     this.isCurrentlyActive = true; 
     if (InactiveWindowOpacity < 1) 
     { 
      base.Opacity = 1; 
     } 
     base.Invalidate(true); 
    } 

    protected override void OnDeactivate(EventArgs e) 
    { 
     base.OnDeactivate(e); 
     this.isCurrentlyActive = false; 
     if (InactiveWindowOpacity < 1) 
     { 
      base.Opacity = InactiveWindowOpacity; 
     } 
     base.Invalidate(true); 
    } 

    protected override void OnResizeEnd(EventArgs e) 
    { 
     base.OnResizeEnd(e); 
     this.framePoints = null; 
     RecalculateWindowFramePoints(); 
     this.Invalidate(true); 
    } 

    private Pen ActivePen 
    { 
     get 
     { 
      if (this.isCurrentlyActive) 
      { 
       if (this.activeWindowFramePen == null) 
       { 
        this.activeWindowFramePen = new Pen(Color.FromArgb((int)(WindowFrameOpacity*255), WindowFrameActiveColor), WindowFrameSize * 2); 
       } 
       return this.activeWindowFramePen; 
      } 
      else 
      { 
       if (this.inactiveWindowFramePen == null) 
       { 
        this.inactiveWindowFramePen = new Pen(Color.FromArgb((int)(WindowFrameOpacity*255), WindowFrameInactiveColor), WindowFrameSize * 2); 
       } 
       return this.inactiveWindowFramePen; 
      } 
     } 
    } 

    private Point[] RecalculateWindowFramePoints() 
    { 
     if ((WindowFrameType == Forms.WindowFrameType.AllSides) 
      && (this.framePoints != null) 
      && (this.framePoints.Length != 5)) 
     { 
      this.framePoints = null; 
     } 
     if ((WindowFrameType == Forms.WindowFrameType.LeftLine) 
      && (this.framePoints != null) 
      && (this.framePoints.Length != 2)) 
     { 
      this.framePoints = null; 
     } 
     if (this.framePoints == null) 
     { 
      switch (WindowFrameType) 
      { 
       case Forms.WindowFrameType.AllSides: 
        this.framePoints = new Point[5] 
        { 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y), 
         new Point(this.ClientRectangle.X + this.ClientRectangle.Width, this.ClientRectangle.Y), 
         new Point(this.ClientRectangle.X + this.ClientRectangle.Width, this.ClientRectangle.Y + this.ClientRectangle.Height), 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y + this.ClientRectangle.Height), 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y) 
        }; 
        break; 
       case Forms.WindowFrameType.LeftLine: 
        this.framePoints = new Point[2] 
        { 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y), 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y + this.ClientRectangle.Height) 
        }; 
        break; 
      } 
     } 
     return this.framePoints; 
    } 

    private void DrawWindowFrame(object sender, PaintEventArgs e) 
    { 
     if (WindowFrameType == Forms.WindowFrameType.NoFrame) 
     { 
      return; 
     } 
     if ((this.framePoints == null) || (this.framePoints.Length == 0)) 
     { 
      return; 
     } 
     Control ctrl = (Control)(sender); 
     // пересчитаем точки в координатах контрола. 
     List<Point> pts = new List<Point>(); 
     foreach (var p in this.framePoints) 
     { 
      pts.Add(ctrl.PointToClient(this.PointToScreen(p))); 
     } 
     e.Graphics.DrawLines(ActivePen, pts.ToArray()); 
    } 

    public static int WindowFrameSize = 2; 
    public static WindowFrameType WindowFrameType = Forms.WindowFrameType.NoFrame; 
    public static Color WindowFrameActiveColor = Color.YellowGreen; 
    public static Color WindowFrameInactiveColor = SystemColors.ControlDark; 
    public static double InactiveWindowOpacity = 1.0; 
    public static double WindowFrameOpacity = 0.3; 
    #endregion 

靜態字段從應用程序設置形式(類)初始化 - 因此,所有在形式該應用程序具有相同的行爲。

希望對某人有幫助。

相關問題