Winforms的 – 如何创build自定义窗口边框和closures/最小化button?

我希望能够创build一个黑色的自定义窗口(带有边框和控件),就像expression式混合,Twirl或Adobe Lightroom的一部分一样。

是否有创build一个所有者绘制窗口的最佳实践方法?

平台:C#和WindowsForms(任何版本)

在WinForms应用程序中自定义标题栏/ chrome

如果自定义的镀铬工具不能为您提供所需的外观,那么这种事情在C#中很容易实现。 基本上,你创建一个无边框的形式(FormBorderStyle = None),然后自己创建所有的控件和边框,把控件放在你需要的地方(标题栏的标签,关闭和最小化的命令按钮等)和/或绘图直接使用Graphics对象在表单的表面上。

您还必须实现代码,以允许窗体被其“假”标题栏拖动(有关如何执行此操作的示例,请参阅此答案 )。 您可能还必须实现您自己的调整大小机制(如果您需要表单可调整大小)。

最后,尽管自定义表单代码可能有点笨拙,但是可以在单一表单上实现,然后让应用程序中的所有其他表单继承此表单,这对于定制整个表单应用。

我的任务是使活动窗口更明显,明亮 – 比其他人,应用程序的非活动窗口。 应用程序有很多打开的窗口,一些模式,一些模式 – 和MDI的父母。

你可以使用像非边界 – 客户区内的框架。 这是代码片段,是基类的一部分(可以直接在表单中使用):

#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 

类的静态字段是从应用程序设置表单(类)初始化的 – 所以,应用程序中的所有表单都具有相同的行为。

希望有助于某人。