使用面板在 C# 中创建自定义 Windows Forms






4.73/5 (51投票s)
在本文中,我们将使用不同颜色的面板来自定义基本的 Windows 窗体,以实现不同的 UI 设计,例如 Visual Studio 中的 Microsoft Office 2013,使用 C#。
引言
我想在 C# 中创建自定义 Windows 窗体。在处理此代码之前,我开始在互联网上寻找任何可以帮助我创建 C# 自定义 Windows 窗体的代码。但不幸的是,我找不到任何简单有用的代码。我找到了一些代码,但它们都很复杂。当我开始着手解决这个问题时,我想到
- 使用自定义面板/面板作为框架的边框来改变窗体的大小,例如宽度、高度等,并使用自定义按钮作为框架的控制框。
- 使用自定义面板作为框架的顶层标题边框,并使用标签显示框架的文本。
- 要在框架上显示图标,我们将背景图像设置为添加的面板。
- 将鼠标事件应用于面板并更改窗体属性。
它工作得很好。
您需要 Visual Studio Professional 2013 或更高版本以及 .NET Framework 4.5 或更高版本才能打开项目。
正确执行以下所有步骤以创建自定义 Windows 窗体。
我们还可以只使用面板创建扩展的高级窗体。(请参阅上面的图像,图像 1 和 2)
下载源代码以查看这些窗体的代码。
请参阅上图以更好地理解文件中的自定义窗体和 BlackForm.cs 的大小调整。
在本文中,我们将创建蓝色可调整大小的自定义 Windows 窗体,根据需要更改面板和按钮的颜色。您可以使用自定义控件来设计窗体。没有自定义控件?
使用以下过程,您还可以为任何 winform 应用程序(如 Word、PowerPoint、Excel 等)设计 Microsoft Office 2013 UI。如下图所示的 Word 截图。
下载 Office_Word_PP_Excel.zip 文件以查看 Word、PowerPoint、Excel、DarkWord 的 UI 代码。
Start
步骤 1
- 启动 Visual Studio 并在 C# 中创建新的 Windows 窗体应用程序项目。我创建了 CustomWindowsForm 项目。
- 下载源代码并查看 BlueForm.cs 的代码。
- 现在为创建的窗体 (Form1) 设置以下属性。
ControlBox | false |
BackColor | 30,60,150 |
FormBorderStyle | 无 |
大小 | 684,461 |
要添加图标,您可以再次添加面板/图片框/工具栏并将其背景图像设置为用作窗口图标。
第二步
- 现在,转到“项目”->“添加类”
- 输入名称
ButtonZ
并单击“添加”。 - 现在将以下
ButtonZ
代码复制并粘贴到您创建的ButtonZ
类代码中。此按钮代码是窗体的关闭和最小化按钮。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace CustomWindowsForm
{
public class ButtonZ : System.Windows.Forms.Button
{
Color clr1;
private Color color = Color.Teal;
private Color m_hovercolor = Color.FromArgb(0, 0, 140);
private Color clickcolor = Color.FromArgb(160, 180, 200);
private int textX = 6;
private int textY = -20;
private String text = "_";
public String DisplayText
{
get { return text; }
set { text = value; Invalidate(); }
}
public Color BZBackColor
{
get { return color; }
set { color = value; Invalidate(); }
}
public Color MouseHoverColor
{
get { return m_hovercolor; }
set { m_hovercolor = value; Invalidate(); }
}
public Color MouseClickColor1
{
get { return clickcolor; }
set { clickcolor = value; Invalidate(); }
}
public int TextLocation_X
{
get { return textX; }
set { textX = value; Invalidate(); }
}
public int TextLocation_Y
{
get { return textY; }
set { textY = value; Invalidate(); }
}
public ButtonZ()
{
this.Size = new System.Drawing.Size(31, 24);
this.ForeColor = Color.White;
this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.Font = new System.Drawing.Font("Microsoft YaHei UI", 20.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Text = "_";
text = this.Text;
}
//method mouse enter
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
clr1 = color;
color = m_hovercolor;
}
//method mouse leave
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
color = clr1;
}
protected override void OnMouseDown(MouseEventArgs mevent)
{
base.OnMouseDown(mevent);
color = clickcolor;
}
protected override void OnMouseUp(MouseEventArgs mevent)
{
base.OnMouseUp(mevent);
color = clr1;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
text = this.Text;
if (textX == 100 && textY == 25)
{
textX = ((this.Width) / 3) + 10;
textY = (this.Height / 2) - 1;
}
Point p = new Point(textX, textY);
pe.Graphics.FillRectangle(new SolidBrush(color), ClientRectangle);
pe.Graphics.DrawString(text, this.Font, new SolidBrush(this.ForeColor), p);
}
}
}
步骤 3
- 现在,转到“项目”->“添加类”
- 输入名称
MinMaxButton
并单击“添加”。 - 现在将以下
MinMaxButton
代码复制并粘贴到您创建的MinMaxButton
类代码中。
此代码用于在窗体最大化时创建最大化和恢复按钮。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace CustomWindowsForm
{
public class MinMaxButton : System.Windows.Forms.Button
{
Color clr1;
private Color color = Color.Gray;
private Color m_hovercolor = Color.FromArgb(180, 200, 240);
private Color clickcolor = Color.FromArgb(160, 180, 200);
private int textX = 6;
private int textY = -20;
private String text = "_";
public enum CustomFormState
{
Normal,
Maximize
}
CustomFormState _customFormState;
public CustomFormState CFormState
{
get { return _customFormState; }
set { _customFormState = value; Invalidate(); }
}
public String DisplayText
{
get { return text; }
set { text = value; Invalidate(); }
}
public Color BZBackColor
{
get { return color; }
set { color = value; Invalidate(); }
}
public Color MouseHoverColor
{
get { return m_hovercolor; }
set { m_hovercolor = value; Invalidate(); }
}
public Color MouseClickColor1
{
get { return clickcolor; }
set { clickcolor = value; Invalidate(); }
}
public int TextLocation_X
{
get { return textX; }
set { textX = value; Invalidate(); }
}
public int TextLocation_Y
{
get { return textY; }
set { textY = value; Invalidate(); }
}
public MinMaxButton()
{
this.Size = new System.Drawing.Size(31, 24);
this.ForeColor = Color.White;
this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.Text = "_";
text = this.Text;
}
//method mouse enter
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
clr1 = color;
color = m_hovercolor;
}
//method mouse leave
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
color = clr1;
}
protected override void OnMouseDown(MouseEventArgs mevent)
{
base.OnMouseDown(mevent);
color = clickcolor;
}
protected override void OnMouseUp(MouseEventArgs mevent)
{
base.OnMouseUp(mevent);
color = clr1;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
switch (_customFormState)
{
case CustomFormState.Normal:
pe.Graphics.FillRectangle(new SolidBrush(color), ClientRectangle);
//draw and fill thw rectangles of maximized window
for (int i = 0; i < 2; i++)
{
pe.Graphics.DrawRectangle(new Pen(this.ForeColor), textX + i + 1, textY, 10, 10);
pe.Graphics.FillRectangle(new SolidBrush(this.ForeColor), textX + 1, textY - 1, 12, 4);
}
break;
case CustomFormState.Maximize:
pe.Graphics.FillRectangle(new SolidBrush(color), ClientRectangle);
//draw and fill thw rectangles of maximized window
for (int i = 0; i < 2; i++)
{
pe.Graphics.DrawRectangle(new Pen(this.ForeColor), textX + 5, textY, 8, 8);
pe.Graphics.FillRectangle(new SolidBrush(this.ForeColor), textX + 5, textY - 1, 9, 4);
pe.Graphics.DrawRectangle(new Pen(this.ForeColor), textX + 2, textY + 5, 8, 8);
pe.Graphics.FillRectangle(new SolidBrush(this.ForeColor), textX + 2, textY + 4, 9, 4);
}
break;
}
}
}
}
步骤 4
运行您的窗体并退出它。用于为拖放组件创建上述代码的控件。
步骤 5
- 将面板拖放到窗体上 (
TopBorderPanel
) - 为拖放的面板设置以下属性。
名称 | TopBorderPanel |
BackColor | 10,20,50 |
光标 | SizeNS |
Dock | 顶部 |
大小 | 684,2 |
步骤 6
- 将面板拖放到窗体上 (
TopPanel
) - 为拖放的面板设置以下属性。
名称 | TopPanel |
BackColor | 20,40,80 |
光标 | 默认值 |
Dock | 顶部 |
大小 | 680,35 |
步骤 7
- 将面板拖放到窗体上 (
LeftPanel
) - 为拖放的面板设置以下属性。
名称 | LeftPanel |
BackColor | 10,20,50 |
光标 | SizeWE |
Dock | 左侧 |
大小 | 2,459 |
步骤 8
- 将面板拖放到窗体上 (
RightPanel
) - 为拖放的面板设置以下属性。
名称 | RightPanel |
BackColor | 10,20,50 |
光标 | SizeWE |
Dock | 右侧 |
大小 | 2,459 |
步骤 9
- 将面板拖放到窗体上 (
BottomPanel
) - 为拖放的面板设置以下属性。
名称 | BottomPanel |
BackColor | 10,20,50 |
光标 | SizeNS |
Dock | 底部 |
大小 | 680,2 |
第 10 步
- 将 ToolTip 拖放到窗体上
第 11 步
- 将
ButtonZ
拖放到TopPanel
(_CloseButton
) - 为拖放的按钮设置以下属性。
名称 | _CloseButton |
Anchor | Top,Right |
BZBackColor | 20,40,80 |
DisplayText | X |
字体 | Microsoft YaHei UI, 11.25pt, style=Bold |
ForeColor | 白色 |
Location | 639,3 |
MouseClickColor1 | 150,0,0 |
MouseHoverColor | 40,80,180 |
大小 | 35,25 |
文本 | X |
TextLocation_X | 10 |
TextLocation_Y | 4 |
toolTip1 上的 ToolTip | Close |
根据需要调整按钮位置。
第 12 步
- 将
ButtonZ
拖放到TopPanel
(_MinButton
) - 为拖放的按钮设置以下属性。
名称 | _MinButton |
Anchor | Top,Right |
BZBackColor | 20,40,80 |
DisplayText | _ |
字体 | Microsoft YaHei UI, 18pt, style=Bold |
ForeColor | 白色 |
Location | 569,3 |
MouseClickColor1 | 10,20,60 |
MouseHoverColor | 40,80,180 |
大小 | 35,25 |
文本 | _ |
TextLocation_X | 8 |
TextLocation_Y | -14 |
toolTip1 上的 ToolTip | Minimize |
第 13 步
- 将
MinMaxButton
拖放到TopPanel
(_MaxButton
) - 为拖放的按钮设置以下属性。
名称 | _MaxButton |
Anchor | Top,Right |
BZBackColor | 20,40,80 |
CFormState | 正常 |
ForeColor | 白色 |
Location | 604,3 |
MouseClickColor1 | 10,20,60 |
MouseHoverColor | 40,80,180 |
大小 | 35,25 |
TextLocation_X | 11 |
TextLocation_Y | 8 |
toolTip1 上的 ToolTip | Maximize |
对于我们自定义窗体的文本,您可以添加 Label 并将其用作窗体的文本。
第 14 步
在 Form1 的代码中全局添加以下变量
bool isTopPanelDragged = false;
bool isLeftPanelDragged = false;
bool isRightPanelDragged = false;
bool isBottomPanelDragged = false;
bool isTopBorderPanelDragged = false;
bool isWindowMaximized = false;
Point offset;
Size _normalWindowSize;
Point _normalWindowLocation = Point.Empty;
isTopPanelDragged
用于检查鼠标按下事件是否由顶部面板触发。左、右、底、顶边框面板也一样。isWindowMaximized
用于检查_MaxButton
点击事件是否发生。- offset 是一个临时变量,用于存储窗体的位置。
_normalWindowSize
用于在点击_MaxButton
后恢复正常窗口大小,与_normalWindowLocation
类似,仅用于存储窗体位置。
第 15 步
现在在事件框中将事件添加到面板和按钮。鼠标按下、鼠标移动和鼠标抬起事件到面板。
TopBorderPanel
TopBorderPanel_MouseDown
TopBorderPanel_MouseMove
TopBorderPanel_MouseUp
TopPanel
TopPanel_MouseDown
TopPanel_MouseMove
TopPanel_MouseUp
LeftPanel
LeftPanel_MouseDown
LeftPanel_MouseMove
LeftPanel_MouseUp
RightPanel
RightPanel_MouseDown
RightPanel_MouseMove
RightPanel_MouseUp
BottomPanel
BottomPanel_MouseDown
BottomPanel_MouseMove
BottomPanel_MouseUp
_MinButton
_MinButton_Click
_MaxButton
_MaxButton_Click
_CloseButton
_CloseButton_Click
第 16 步
将上述所有事件添加到所有组件后,将您的 *Form1.cs* 代码替换为以下代码。只需更改类、命名空间等。下载源代码以查看简单的蓝色自定义窗体。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CustomWindowsForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
bool isTopPanelDragged = false;
bool isLeftPanelDragged = false;
bool isRightPanelDragged = false;
bool isBottomPanelDragged = false;
bool isTopBorderPanelDragged = false;
bool isWindowMaximized = false;
Point offset;
Size _normalWindowSize;
Point _normalWindowLocation = Point.Empty;
//**********************************************************************
//top border panel
private void TopBorderPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isTopBorderPanelDragged = true;
}
else
{
isTopBorderPanelDragged = false;
}
}
private void TopBorderPanel_MouseMove(object sender, MouseEventArgs e)
{
if (e.Y < this.Location.Y)
{
if (isTopBorderPanelDragged)
{
if (this.Height < 50)
{
this.Height = 50;
isTopBorderPanelDragged = false;
}
else
{
this.Location = new Point(this.Location.X, this.Location.Y + e.Y);
this.Height = this.Height - e.Y;
}
}
}
}
private void TopBorderPanel_MouseUp(object sender, MouseEventArgs e)
{
isTopBorderPanelDragged = false;
}
//**********************************************************************
//top panel
private void TopPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isTopPanelDragged = true;
Point pointStartPosition = this.PointToScreen(new Point(e.X, e.Y));
offset = new Point();
offset.X = this.Location.X - pointStartPosition.X;
offset.Y = this.Location.Y - pointStartPosition.Y;
}
else
{
isTopPanelDragged = false;
}
if (e.Clicks == 2)
{
isTopPanelDragged = false;
_MaxButton_Click(sender, e);
}
}
private void TopPanel_MouseMove(object sender, MouseEventArgs e)
{
if (isTopPanelDragged)
{
Point newPoint = TopPanel.PointToScreen(new Point(e.X, e.Y));
newPoint.Offset(offset);
this.Location = newPoint;
if (this.Location.X > 2 || this.Location.Y > 2)
{
if (this.WindowState == FormWindowState.Maximized)
{
this.Location = _normalWindowLocation;
this.Size = _normalWindowSize;
toolTip1.SetToolTip(_MaxButton, "Maximize");
_MaxButton.CFormState = MinMaxButton.CustomFormState.Normal;
isWindowMaximized = false;
}
}
}
}
private void TopPanel_MouseUp(object sender, MouseEventArgs e)
{
isTopPanelDragged = false;
if (this.Location.Y <= 5)
{
if (!isWindowMaximized)
{
_normalWindowSize = this.Size;
_normalWindowLocation = this.Location;
Rectangle rect = Screen.PrimaryScreen.WorkingArea;
this.Location = new Point(0, 0);
this.Size = new System.Drawing.Size(rect.Width, rect.Height);
toolTip1.SetToolTip(_MaxButton, "Restore Down");
_MaxButton.CFormState = MinMaxButton.CustomFormState.Maximize;
isWindowMaximized = true;
}
}
}
//**********************************************************************
//left panel
private void LeftPanel_MouseDown(object sender, MouseEventArgs e)
{
if (this.Location.X <= 0 || e.X < 0)
{
isLeftPanelDragged = false;
this.Location = new Point(10, this.Location.Y);
}
else
{
if (e.Button == MouseButtons.Left)
{
isLeftPanelDragged = true;
}
else
{
isLeftPanelDragged = false;
}
}
}
private void LeftPanel_MouseMove(object sender, MouseEventArgs e)
{
if (e.X < this.Location.X)
{
if (isLeftPanelDragged)
{
if (this.Width < 100)
{
this.Width = 100;
isLeftPanelDragged = false;
}
else
{
this.Location = new Point(this.Location.X + e.X, this.Location.Y);
this.Width = this.Width - e.X;
}
}
}
}
private void LeftPanel_MouseUp(object sender, MouseEventArgs e)
{
isLeftPanelDragged = false;
}
//**********************************************************************
//right panel
private void RightPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isRightPanelDragged = true;
}
else
{
isRightPanelDragged = false;
}
}
private void RightPanel_MouseMove(object sender, MouseEventArgs e)
{
if (isRightPanelDragged)
{
if (this.Width < 100)
{
this.Width = 100;
isRightPanelDragged = false;
}
else
{
this.Width = this.Width + e.X;
}
}
}
private void RightPanel_MouseUp(object sender, MouseEventArgs e)
{
isRightPanelDragged = false;
}
//**********************************************************************
//bottom panel
private void BottomPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isBottomPanelDragged = true;
}
else
{
isBottomPanelDragged = false;
}
}
private void BottomPanel_MouseMove(object sender, MouseEventArgs e)
{
if (isBottomPanelDragged)
{
if (this.Height < 50)
{
this.Height = 50;
isBottomPanelDragged = false;
}
else
{
this.Height = this.Height + e.Y;
}
}
}
private void BottomPanel_MouseUp(object sender, MouseEventArgs e)
{
isBottomPanelDragged = false;
}
//**********************************************************************
//actions for close,min,max buttons
private void _CloseButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void _MaxButton_Click(object sender, EventArgs e)
{
if (isWindowMaximized)
{
this.Location = _normalWindowLocation;
this.Size = _normalWindowSize;
toolTip1.SetToolTip(_MaxButton, "Maximize");
_MaxButton.CFormState = MinMaxButton.CustomFormState.Normal;
isWindowMaximized = false;
}
else
{
_normalWindowSize = this.Size;
_normalWindowLocation = this.Location;
Rectangle rect = Screen.PrimaryScreen.WorkingArea;
this.Location = new Point(0, 0);
this.Size = new System.Drawing.Size(rect.Width, rect.Height);
toolTip1.SetToolTip(_MaxButton, "Restore Down");
_MaxButton.CFormState = MinMaxButton.CustomFormState.Maximize;
isWindowMaximized = true;
}
}
private void _MinButton_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
}
}
以上所有步骤的输出如下
我们已经创建了一个自定义窗体,因此您无法直接将某些控件(如 MenuStrip、SplitContainer 等)添加到窗体中。要添加这些控件,您首先需要添加面板并将它们添加到该面板上,这样我们的自定义窗体就不会被更改。