winform开发的时候,因为自身窗体都是window窗体风格,可操作性不大,往往不能根据UI提供的方案进行界面的UI搭建。因此会采用自定义的窗体作为父类窗体,将所有界面统一风格并避免代码重写。当然,如果需要实现很漂亮的界面,还是建议wpf或者Unity或其他方式实现,winform的控件有一定的局限性,有时候UI设计的按钮或者其他控件达不到效果,可能需要控件重绘来解决,相对来说不是那么友好。
如下图所示的风格,实现之后,可以直接像Form类一样使用。
全部代码在此
目录
基础讲解最小化、最大化、关闭功能实现自定义属性窗体大小自由拖拽实现窗体可拖动基础讲解
首先是新建一个窗体A,作为之后所有窗体的父类,这样的好处就是需要修改皮肤的时候,不用一个个改,只需要修改这个父类窗体A即可。
A的属性设置需要如下:
去掉原有的标题栏,自己用图片控件或者Panel搭建标题头
使用该皮肤只需要继承该窗体即可。
最小化、最大化、关闭功能实现
private void pb_min_Click(object sender, EventArgs e){this.WindowState = FormWindowState.Minimized;}private void pb_max_min_Click(object sender, EventArgs e){MaxNormalSwitch();}private void pb_close_Click(object sender, EventArgs e){this.Close();}/// <summary>/// 最大化和正常状态切换/// </summary>private void MaxNormalSwitch(){if (this.WindowState == FormWindowState.Maximized)//如果当前状态是最大化状态 则窗体需要恢复默认大小{this.WindowState = FormWindowState.Normal;//this.pb_max_min.Image = FormAndUserControls.Properties.Resources.最大化1;}else{//防止遮挡任务栏//this.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height);this.WindowState = FormWindowState.Maximized;//最大化图标切换this.pb_max_min.Image = FormAndUserControls.Properties.Resources.最大化;}this.Invalidate();//使重绘}
自定义属性
属性支持自定义,则使用的时候,能在属性模块直接修改。如下所示,在属性的杂项中。
可根据自己的需要添加其他自定义属性。
/// <summary>/// 窗体标题/// </summary>private string titleText;[Description("窗体标题")]public string TitleText{get {return titleText; }set{titleText = value;lb_Tilte.Text = titleText;this.Text = value;}}/// <summary>/// 窗体标题是否显示/// </summary>private bool titleVisible = true;[Description("窗体标题是否显示")]public bool TitleVisible{get {return titleVisible; }set{titleVisible = value;lb_Tilte.Visible = titleVisible;}}/// <summary>/// 窗口默认大小/// FormSize.NORMAL OR FormSize.MAX/// </summary>private FormWindowState defaultFormSize = FormWindowState.Normal;[Description("窗口默认大小")]public FormWindowState DefaultFormSize{get {return defaultFormSize; }set{defaultFormSize = value;MaxNormalSwitch();}}
窗体大小自由拖拽
我用的是几个panel用来确定从哪里拖拽,也有其他方式,比如判断鼠标是否移出窗体之类的,个人习惯下面的方式实现。
如图,红色区域放置了几个panel
对panel设置属性(例如右边竖线panel,是用来控制窗体右边宽度调整):
设置其随着窗体高度变化而变化
设置鼠标出现在上面的时候显示左右移动的箭头
所有panel可根据需要实现的效果设置完成。
添加拖拽事件(例如左右两边的是水平拖拽,最下面是上下拖拽,两个角为对角线拖拽):
绑定代码如下:
#region 窗体大小自由更改//改变窗体大小public const int WMSZ_LEFT = 0xF001;public const int WMSZ_RIGHT = 0xF002;public const int WMSZ_TOP = 0xF003;public const int WMSZ_TOPLEFT = 0xF004;public const int WMSZ_TOPRIGHT = 0xF005;public const int WMSZ_BOTTOM = 0xF006;public const int WMSZ_BOTTOMLEFT = 0xF007;public const int WMSZ_BOTTOMRIGHT = 0xF008;public void SetSize(int type){ReleaseCapture();SendMessage(this.Handle, WM_SYSCOMMAND, type, 0);this.pb_max_min.Image = FormAndUserControls.Properties.Resources.最大化1;}//上下拖拽绑定的事件private void Form1_MouseDownVertical(object sender, MouseEventArgs e){//Cursor = Cursors.SizeNS;SetSize(WMSZ_BOTTOM);}//水平拖拽绑定的事件private void Form1_MouseDownHorizontal(object sender, MouseEventArgs e){if (sender is Panel panel){int type = 0;switch (panel.Tag.ToString()){case "0":type = WMSZ_LEFT;break;case "1":type = WMSZ_RIGHT;break;}SetSize(type);}}//左对角线拖拽绑定的事件private void Form1_MouseDownLeftAndButtom(object sender, MouseEventArgs e){SetSize(WMSZ_BOTTOMLEFT);}//右对角线拖拽绑定的事件private void Form1_MouseDownRightAndButtom(object sender, MouseEventArgs e){SetSize(WMSZ_BOTTOMRIGHT);}public void AdjuestSize(){panel11.Location = new Point(this.Width - panel11.Width, panel11.Location.Y);panel11.Height = this.Height - 20;panel3.Width = this.Width - panel3.Location.X ;panel4.Location = new Point(this.Width - panel4.Width, panel4.Location.Y);panel6.Height = this.Height - panel6.Location.Y - 15;panel8.Location = new Point(panel8.Location.X, this.Height - panel8.Height);panel9.Location = new Point(15, panel8.Location.Y);panel9.Width = this.Width - panel9.Location.X - 10;panel10.Location = new Point(this.Width - 32, this.Height - 32);//panel_control.Size = new Size(this.Width- panel_control.Location.X- buttomWidth, this.Height- panel_control.Location.Y-10);}private void MyForm_Load(object sender, EventArgs e){AdjuestSize();//必须在此调整位置}#endregion
实现窗体可拖动
#region 实现边框拖拽[DllImport("user32.dll")]//拖动无窗体的控件public static extern bool ReleaseCapture();[DllImport("user32.dll")]public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);public const int WM_SYSCOMMAND = 0x0112;public const int SC_MOVE = 0xF010;public const int HTCAPTION = 0x0002;private void Form1_MouseDown(object sender, MouseEventArgs e){//拖动窗体ReleaseCapture();SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);this.pb_max_min.Image = FormAndUserControls.Properties.Resources.最大化1;}#endregion