c#-winform自定义窗体皮肤(无边框皮肤)

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
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yyuanyuxin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值