C#自定义窗口形状


首先,设置窗体的背景从而建立窗体形状。

 

1.在窗体设计器中选中窗体使之获得焦点。

 

2.在属性对话框中进行如下设置:

 

● 将FormBorderStyle属性设置为None。该属性去掉了程序的标题栏,同时也除去了标题栏的功能,不过我在后面还会向大家介绍如何添加代码以 恢复这些功能的。

 

● 将BackgroundImage属性设置为你创建的位图文件。你不必在工程中添加该文件,因为你一旦指定了该文件,它就会自动被添加到工程中。

 

● 将TransparencyKey属性设置为位图文件的背景颜色值(在本例中是蓝色)。该属性使得位图的背景即上图中的蓝色部分不可见,从而窗体就呈现出一个不规则的椭圆形。

 

 

特别要注意的是:如果监视器的颜色深度设置大于 24 位,则不管 TransparencyKey 属性是如何设置的,窗体的非透明部分都会产生显示问题。若要避免出现这种问题,请确保“显示”控制面板中的监视器颜色深度的设置小于 24 位。当开发具有这种透明功能的应用程序时,请牢记应使您的用户意识到此问题。

 

 

 

3. 保存工程。先Ctrl+S保存,然后按Ctrl+F5可以运行此程序。(注:因为没有标题栏,所以你可以通过Alt+F4来关闭程序)

 

 

 

将FormBorderStyle属性设置为None后,程序的标题栏就被去掉了。这样,为 了获得原来标题栏的功能,我们必须手动添加代码。下面我就向大家介绍如何添加代码实现关闭功能以及移动窗体的功能。

 

实现窗体的关闭及移动

 

1.往窗体上拖放一个按钮控件。

 

2.在属性对话框中,将该控件的Text属性设置为“关闭”。

 

3.双击按钮添加一个Click事件处理函数。

 

4.在代码编辑器中添加如下代码:

 

private void button1_Click(object sender, System.EventArgs e)

 

{

 

   this.Close();

 

}

 

5. 接下来就是实现窗体的移动功能。添加以下代码来创建一个Point对象,该对象(作为一个变量)决定在什么情况下移动窗体。

 

private Point mouse_offset;

 

6. 创建窗体的MouseDown事件的事件处理函数。为该事件添加代码后,用户就可以在任何位置移动窗体了。代码如下:

 

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)

 

{

 

      mouse_offset = new Point(-e.X, -e.Y);

 

}

 

7. 创建窗体的MouseMove事件的事件处理函数。当鼠标左键被按下,同时鼠标被移动时,窗体的Location属性就被设置为新的位置了,这样窗体就被用户拖动了。

 

private void Form1_MouseMove(object sender,

 

 System.Windows.Forms.MouseEventArgs e)

 

{

 

   if (e.Button == MouseButtons.Left)

 

   {

 

      Point mousePos = Control.MousePosition;

 

      mousePos.Offset(mouse_offset.X, mouse_offset.Y);

 

      Location = mousePos;

 

   }

 

c# 改变窗体形状(2)

 

 

创建自定义形 状的控件

 

现在,我们已经创建了一 个不规则的窗体,并实现了一些基本的移动窗体、关闭窗体的功能。然 而,窗体上的按钮控件还是老一套,那么方方正正,使得整个界面不美观。接下来我就向大家介绍如何创建自定义形状的控件。

 

前面我们创建不规则窗体 的时候用到了TransparencyKey属性,但是控件是没有该属性的,所以我们得找其他的方法来实现控件的不规则形状了。在窗体上画一个自定义形状的控件时,你需要精确的告知窗体在什么位置以及如何画该控件。 在.Net Framework中有相应的类和方法来帮你实现这些,所以你不必担心具体实现。

 

.Net Framework中的类提供给控件一个指示说明,该指示说明能确定控件被画的形状。通过不同的指示说明,你就可以按你想要的方法来画 控件了。该指示说明利用了GraphicsPath这个类,这个类代表了一系列用来画图的直线和曲线。首先,你得指定 一个GraphicsPath类的对象并告知它你要画什 么图形。然后,你将控件的Region属性设置为上述GraphicsPath类 的对象。这样,你就可以创建任何自定义形状的控件了。

 

步骤如下:

 

●创建一 个GraphicsPath类的实例对象。

 

●指定好 该对象的各项细节(如大小、形状等等)。

 

●将控件 的Region属性设置为上面建立的GraphicsPath类 的实例对象。

 

创建一个像文本的按钮控 件:

 

1.拖放 一个按钮控件到窗体上。

 

2.在属 性对话框中进行如下设置:

 

●将Name属性设置为CustomButton。

 

●将BackColor属性设置为一个和窗体背景颜色不同的颜色值。

 

●将其Text属性设置为空字符串。

 

3.添加 窗体的Paint事件的事件处理函数。

 

4.添加 以下代码,用GraphicsPath类的实例对象来画控件。下面的代码以一串字符 串的形式画该按钮控件,同时,程序还设置了字符串的字体、大小、风格等属性。字符串被赋给GraphicsPath类 的实例对象。然后,该实例对象就被设 置为按钮控件的Region属性。这样一个自定义形状的控件就完成了。

 

private void CustomButton_Paint(object sender,

 

System.Windows.Forms.PaintEventArgs e)

 

{

 

   //初始化一个GraphicsPath类的对象

 

   System.Drawing.Drawing2D.GraphicsPath myGraphicsPath  = new

 

System.Drawing.Drawing2D.GraphicsPath();

 

   //确定一个字符 串,该字符串就是控件的形状

 

   string stringText = "Click Me!";

 

   //确定字符串的字 体

 

   FontFamily family = new FontFamily("Arial");

 

   //确定字符串的风 格

 

   int fontStyle = (int)FontStyle.Bold;

 

   //确定字符串的高 度

 

   int emSize = 35;

 

   //确定字符串的起 始位置,它是从控件开始计算而非窗体

 

   PointF origin = new PointF(0, 0);

 

   //一个StringFormat对象来确定字符串的字间距以及对齐方式

 

   StringFormat format = new StringFormat(StringFormat.GenericDefault);

 

   //用AddString方法创建字符串

 

   myGraphicsPath.AddString(stringText, family, fontStyle, emSize, origin, format);

 

   //将控件的Region属性设置为上面创建的GraphicsPath对 象

 

   CustomButton.Region = new Region(myGraphicsPath);

 

}

 

5. 创建按钮的Click事件的事件处理函数。添加该处理函数来改变控件的背景颜色,从而证实控件原来 的那些功能没有被削减。

 

private void CustomButton_Click(object sender, System.EventArgs e)

 

{

 

   CustomButton.BackColor = Color.BlanchedAlmond;

 

}

 

6.保存 工程并运行。

 

进一步优化效 果

 

以上我们运用了GraphicsPath类的实例对象来创建了自定义形状的一个按钮控件。不过我们用的是文本字符串形式的一个形状,是否可以用三角形或是圆形等形状呢?答案是肯定的。.Net Framework能为我们提供一些预先定义好了的形状以供我们在程序中使用。通过运用这些,你可以创造出几乎任意形状的控件,你还可以把它们结合起来使 用以发挥更大的功能。

 

下面的实例就运用了四个 椭圆,当它们被运用到控件上后,看起来就像人的眼睛,很有意思吧。

 

private void button1_Paint(object sender,

 

System.Windows.Forms.PaintEventArgs e)

 

{

 

   System.Drawing.Drawing2D.GraphicsPath myGraphicsPath  = new

 

System.Drawing.Drawing2D.GraphicsPath();

 

   myGraphicsPath.AddEllipse(new Rectangle(0, 0, 125, 125));

 

   myGraphicsPath.AddEllipse(new Rectangle(75, 75, 20, 20));

 

   myGraphicsPath.AddEllipse(new Rectangle(120, 0, 125, 125));

 

   myGraphicsPath.AddEllipse(new Rectangle(145, 75, 20, 20));

 

   //改变按钮的背景 颜色使之能被容易辨认

 

   button1.BackColor = Color.Chartreuse;

 

   button1.Size = new System.Drawing.Size(256, 256);

 

   button1.Region = new Region(myGraphicsPath);

 

 

 

}

 

最后,你还得搞清楚窗体 类是从System.Windows.Forms.Control类继承而来的。也就是说,由窗体设计器提供给你的窗体最终还是一个控件。因此,你能用位图文件创建一个不规则的窗体,你还能用GraphicsPath类对象来像创建自定义形状的控件那样创建不规则的窗体。有兴趣的读者不妨用此方法一试效果。

 

一个更好的例 子

 

下面我给大家介绍一个更 好的例子,该实例的界面就和微软的WindowsMedia Player 7的界面差不多。不 过在这个例子中,我只是介绍了如何制作出界面,并没有实现媒体播放的功能,要实现那些功能,还需要您自行完善。该实例运行的界面如下:

 

1.将某 种颜色设置为窗体的背景颜色,然后将窗体的TransparenceKey属性设置 为那种颜色,同时将窗体的FormBorderStyle属性设置为None。

 

2.重载Form_Paint()函数:

 

protected override void  OnPaint(PaintEventArgs e)

 

或是this.Paint += new System.Windows.Form.PaintEventHandler(Form_Paint)。

 

3.程序 的主体部分的函数如下:

 

private void Form_Paint(object sender, PaintEventArgs e)

 

 {

 

  Graphics g = e.Graphics;

 

   Rectangle mainRect = new Rectangle(0, 0, 695, 278);

 

   Region mainRegion = new Region(mainRect);

 

   e.Graphics.SetClip(mainRegion, CombineMode.Replace);

 

       Point point1 = new Point(0, 32);

 

   Point point2 = new Point(9, 20);

 

   Point point3 = new Point(21, 13);

 

   Point point4 = new Point(34, 9);

 

       // 创建一个以点 为元素的数组

 

   Point[] curvePoints = { point1, point2, point3, point4 };

 

   // 创建一个GraphicsPath对象并添加一条曲线

 

   GraphicsPath myPath = new GraphicsPath();

 

   myPath.AddCurve(curvePoints, 0, 3, 0.8f);

 

   myPath.AddLine(36, 9, 378, 9);

 

   point1.X=378;point1.Y=9;

 

   point2.X=387;point2.Y=5;

 

   point3.X=394;point3.Y=0;

 

   Point[] curvePoints2 = { point1, point2, point3 };

 

   myPath.AddCurve(curvePoints2, 0, 2, 0.8f);

 

   myPath.AddLine(394, 0, 0, 0);

 

   Region ExcludeRegion3 = new Region(myPath);

 

   e.Graphics.ExcludeClip(ExcludeRegion3);

 

 

 

   GraphicsPath myPath3 = new GraphicsPath();

 

   point1.X=0;point1.Y=180;

 

   point2.X=19;point2.Y=198;

 

   point3.X=62;point3.Y=204;

 

   point4.X=83;point4.Y=221;

 

   Point point5 = new Point(93, 248);

 

   Point point6 = new Point(102, 267);

 

   Point point7 = new Point(125, 278);

 

   Point[] curvePoints3 = { point1, point2, point3, point4,

 

point5, point6, point7 };

 

   myPath3.AddCurve(curvePoints3, 0, 6, 0.8f);

 

   myPath3.AddLine(125, 278, 90, 300);

 

   myPath3.AddLine(90, 300, 0, 300);

 

   Region ExcludeRegion2 = new Region(myPath3);

 

   e.Graphics.ExcludeClip(ExcludeRegion2);

 

   point1.X=454;point1.Y=0;

 

   point2.X=470;point2.Y=12;

 

   point3.X=481;point3.Y=34;

 

   Point[] curvePoints4 = { point1, point2, point3 };

 

   GraphicsPath myPath2 = new GraphicsPath();

 

   myPath2.AddCurve(curvePoints4, 0, 2, 0.8f);

 

   myPath2.AddLine(481, 30, 481, 76);

 

   myPath2.AddLine(481, 76, 495, 76);

 

   myPath2.AddLine(495, 76, 495, 0);

 

   Region ExcludeRegion4 = new Region(myPath2);

 

   e.Graphics.ExcludeClip(ExcludeRegion4);

 

   GraphicsPath myPath5 = new GraphicsPath();

 

   point1.X=481;point1.Y=76;

 

   point2.X=494;point2.Y=115;

 

   point3.X=481;point3.Y=158;

 

   Point[] curvePoints5 = { point1, point2, point3 };

 

   myPath5.AddCurve(curvePoints5, 0, 2, 0.8f);

 

   myPath5.AddLine(481, 158, 481, 279);

 

   myPath5.AddLine(481, 255, 495, 279);

 

   myPath5.AddLine(495, 279, 495, 0);

 

   Region ExcludeRegion6 = new Region(myPath5);

 

   e.Graphics.ExcludeClip(ExcludeRegion6);

 

 

 

   point1.X=480;point1.Y=250;

 

   point2.X=469;point2.Y=264;

 

   point3.X=446;point3.Y=278;

 

   Point[] curvePoints6 = { point1, point2, point3 };

 

   GraphicsPath myPath4 = new GraphicsPath();

 

   myPath4.AddCurve(curvePoints6, 0, 2, 0.8f);

 

   myPath4.AddLine(450, 277, 495, 279);

 

   Region ExcludeRegion5 = new Region(myPath4);

 

   e.Graphics.ExcludeClip(ExcludeRegion5);

 

   e.Graphics.DrawImage(img, 0, 0, 695,278);

 

 

   // 重设剪切好的 区域

 

   e.Graphics.ResetClip();

 

 }


 
   

你可能感兴趣的:(C#)