[C#]绘制自定义窗体

去windows除边框

初始窗口样式:

[C#]绘制自定义窗体_第1张图片

将窗口FormBorderStyle属性设为None,就可以去除四周边框

[C#]绘制自定义窗体_第2张图片

此时窗口将成为什么也没有的一个白板。

 

标题栏

标题栏

拖一个panel控件到窗体上,设置背景图片,作为标题栏。

窗口图标和主题

用一个PictureBox作为Logo,导入图片,并将BackColor属性设为Transparent。

用一个Label作为窗口主题,不妨就把Text值设为窗口,BackColor属性设为Transparent。

最小化、关闭按钮

(1)设置按钮样式

首先,拖两个PictureBox控件到标题栏;

然后分别为两个PictureBoxImage设置最小化、关闭按钮的图片;

BackColor的属性设为Transparent。

此时,窗口的效果如下:

[C#]绘制自定义窗体_第3张图片

注:刚开始,我使用的是Button控件作为最小化、关闭按钮。但是不知为什么,有时候按钮周围会出现边框,且无法消除,所以改用PictureBox代替。

有兴趣的朋友可以试一试这个方法:

ButtonText值清除;为ButtonImage导入一个对应图片(如果要和背景色对应上,最好是透明图片);将ButtonBackColor属性设为Transparent;将FlatStyle属性设为Flat,

MouseDownBackColor和MouseOverBackColor属性都设为Transparent,并将BorderSize设为0.

[C#]绘制自定义窗体_第4张图片

 

标题栏的相关事件

基本样式似乎差不多了,但是因为我们隐去了windows默认窗体的标题栏,所以不能拖拽窗口,也不能最小化、关闭窗口。

那么,好吧,我们自己来动手写。

拖拽窗体

为标题栏,也就是我们前面添加的Panel控件添加MouseDownMouseMove两个事件。

然后根据鼠标的位置动态刷新窗体的位置。

代码如下:

private Point offset;
private  void panelTitleBar_MouseDown( object sender, MouseEventArgs e)
{
     if (MouseButtons.Left != e.Button)  return;
    Point cur =  this.PointToScreen(e.Location);
    offset =  new Point(cur.X -  this.Left, cur.Y -  this.Top);
}
 
private  void panelTitleBar_MouseMove( object sender, MouseEventArgs e)
{
     if (MouseButtons.Left != e.Button)  return;
    Point cur = MousePosition;
     this.Location =  new Point(cur.X - offset.X, cur.Y - offset.Y);
}

 

最小化窗口

为最小化按钮,也就是我们添加的PictureBox添加点击事件。

一行代码搞定,设置窗体状态。

private  void pictureBoxMinimize_Click( object sender, EventArgs e)
{
     this.WindowState = FormWindowState.Minimized;
}


关闭窗口

为关闭按钮,添加点击事件。

关闭窗口,释放资源。

private  void pictureBoxClose_Click( object sender, EventArgs e)
{
     this.Close();
     this.Dispose();
}

至此,一个简陋的窗体需要的基本功能就完成了。

 

绘制边框

前面的窗体因为去除了windows窗体的自带边框,所以整个窗体没有边框,显示的时候会有些奇怪,尤其是桌面背景色为白色的时候。

可以使用下面的方法绘制窗体边框

在窗体加载事件中需要将FormBorderStyle属性设为FormBorderStyle.FixedSingle。

#region 窗口边框
//  重绘窗口边框
//  加载窗口时必须使用以下语句才能生效
//  this.FormBorderStyle = FormBorderStyle.FixedSingle;
protected  override CreateParams CreateParams
{
     get
    {
         const  int WS_CAPTION =  0xC00000;
         const  int WS_BORDER =  0x800000;
        CreateParams CP =  base.CreateParams;
        CP.Style &= ~WS_CAPTION | WS_BORDER;
         return CP;
    }
}
#endregion
 
private  void Form1_Load( object sender, EventArgs e)
{
     this.FormBorderStyle = FormBorderStyle.FixedSingle;
}

运行后,效果如下:

[C#]绘制自定义窗体_第5张图片


绘制阴影 

第一种方式

缺点:如果不是windows默认窗体,则只有右下角有阴影效果。 

引用System.Runtime.InteropServices;

private  void Form1_Load( object sender, EventArgs e)
{
    SetClassLong( this.Handle, GCL_STYLE, GetClassLong( this.Handle, GCL_STYLE) | CS_DropSHADOW);
}

private  const  int CS_DropSHADOW =  0x20000;
private  const  int GCL_STYLE = (- 26);
[DllImport( " user32.dll ", CharSet = CharSet.Auto)]
public  static  extern  int SetClassLong(IntPtr hwnd,  int nIndex,  int dwNewLong);
[DllImport( " user32.dll ", CharSet = CharSet.Auto)]
public  static  extern  int GetClassLong(IntPtr hwnd,  int nIndex);

效果图

[C#]绘制自定义窗体_第6张图片 


第二种方式:

感谢乔克斯的方法,原址:http://bbs.cskin.net/thread-61-1-1.html

添加引用SkinForm.dll,然后using CCWin

最后让Form对象继承SkinMain类即可。

using System;
using System.Drawing;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using CCWin;

namespace WinformTest
{
     public  partial  class PrivateForm : SkinMain
    {
         public PrivateForm()
        {
            InitializeComponent();
        }

         private  void Form1_Load( object sender, EventArgs e)
        {
             // SetClassLong(this.Handle, GCL_STYLE, GetClassLong(this.Handle, GCL_STYLE) | CS_DropSHADOW);
        }

        ... ...
    }
}

效果如下:

[C#]绘制自定义窗体_第7张图片

至此,一个简易的自定义窗口就实现了,还像个样子吧。

 

参考资料

http://www.sufeinet.com/thread-9411-1-1.html
http://bbs.cskin.net/thread-61-1-1.html

你可能感兴趣的:([C#]绘制自定义窗体)