Winform自定义窗体与控件的外观形状
来源:互联网 发布:冷轩网络 编辑:程序博客网 时间:2024/04/29 04:40
在开发的时候,有时我们需要自定义窗体,各种奇怪的形状都有可能,这里举一个利用Region自定义外观的例子。下图就是一个自定义十字形的窗体,和一个居中显示的蓝色自定义外形的按钮。
代码可以分为两个部分,一个是绘制按钮的,一个是绘制窗体的。窗体外形定义比较简单,只是用了四行代码,当然,这也是因为外观简单而已;其余的代码都是为自定义按钮服务的。
public class SpecialRegionForm : Form { public SpecialRegionForm() { this.FormBorderStyle = FormBorderStyle.None; Region btnRegion = null; GraphicsPath path = null; path = new GraphicsPath(); path.AddEllipse(0, 0, 100, 100); btnRegion = new Region(path); path = new GraphicsPath(); path.AddRectangle(new Rectangle(25, 25, 50, 50)); btnRegion.Exclude(new Region(path)); path = new GraphicsPath(); path.AddLines(new Point[]{new Point(50, 25), new Point(25, 50), new Point(50, 75), new Point(75, 50)}); btnRegion.Union(new Region(path)); path = new GraphicsPath(); path.AddRectangle(new Rectangle(50, 0, 50, 1)); //path.AddLine(50, 0, 100, 0); btnRegion.Union(new Region(path)); Button testButton = new Button(); testButton.Location = new Point(100, 100); testButton.Width = 100; testButton.Height = 100; testButton.Text = "^o^"; testButton.Region = btnRegion; testButton.BackColor = Color.Blue; testButton.Cursor = Cursors.Hand; testButton.Click += new EventHandler(delegate(object sender, System.EventArgs e) { if (DialogResult.Yes.Equals(MessageBox.Show("Are you sure to exit?", "Exit?", MessageBoxButtons.YesNo))) { this.Close(); } }); this.Controls.Add(testButton); Region vertical = new Region(new Rectangle(100, 0, 100, 300)); Region horizontal = new Region(new Rectangle(0, 100, 300, 100)); vertical.Union(horizontal); this.Region = vertical; } }我们先从简单的窗体外观自定义入手,由于窗体本身的“非客户区域”(标题栏、菜单栏)会占用我们常用的“客户区域”,所以在构造函数的第一行我们就把外形样式设置成NONE,这样就不会受“非客户区域”的干扰了。现在我们集中观察最后四行代码,首先需要定义一个横向居中的垂直矩形,然后再定义一个纵向居中的水平矩形,最后利用一个“并”——Union操作,把两个矩形合并,得到一个合并后的区域。把这个合并后的区域赋值给当前窗体后,就可以让窗体按照我们设计的区域进行显示了。
窗体定义完毕,下面该轮到按钮了,这个过程与窗体定义基本类似,显示定义自定义显示区域,然后再把显示区域赋值给按钮,但是需要注意一点,由于按钮本身大小的默认值远远小于我们给出的自定义区域面积,所以我们需要适当地加大按钮的宽和高。另外为了显示明显,按钮的背景颜色和鼠标光标也被定制了(蓝色+手势)。因为窗体样式为None,所以我们应该提供一个退出的方法,所以需要绑定一个Click事件为了退出当前程序。OK,这些内容都了解完之后,我们就可以把重点放在外观自定义上了。从上面的截图可以看出,按钮主要有两个部分组成,一个铜钱加一个旋转45度的正方形。看到这里,我们可能会想到,这和前面的窗体完全是两回事,不是简简单单的两个矩形就能搞得定的(多了个圈圈嘛:)。
对于复杂形状来说,我们可以用两种方法来达到目的,一是Region提供的Union、Intersect、Exclude、Xor和Complement,另一个则是用了绘制各种复杂图像的GraphicsPath对象,并且,.Net还允许我们把这两者结合起来使用。从上面的代码中可以看出,首先我们定义了一个圆形的区域,具体操作是利用定义好的GraphicsPath对象创建圆形,然后把GraphicsPath对象转成Region对象;接下来再定义一个正方形,并在当前已经生成的圆形区域基础上,利用Region.Exclude方法把矩形区域剔除;第三步则是要加入一个旋转45度的矩形,这里有两种实现方法,一种是创建一个矩形,然后GraphicsPath.Transform来进行旋转(可以参考http://www.c-sharpcorner.com/UploadFile/mgold/TransformswithGDIplus09142005064919AM/TransformswithGDIplus.aspx);另一种做法就是自己算好尺寸坐标,通过Graphics.DrawLines绘制,这里我们采用的就是这种做法。当第三个区域也绘制好之后,我们就可以把它Union到之前做好的btnRegion了。为了测试单个像素高的内容是否也能有效地参与hit testing(碰撞测试),可以添加一个高度为1像素,宽度为50像素的矩形。最后再把合并了四个(圆-矩+矩+单像素矩)图形的btnRegion指派给testButtion.Region。到这里,我们就完成了自定义按钮外观的定制工作了。
测试的时候需要对镂空区域和非镂空区域进行检测,另外还应该对我们最后加入的单像素矩形进行测试,只要鼠标移到非镂空的蓝色区域和右上角的黑线,鼠标都会变成手势图案,点击时也都会提示我们退出程序。请注意上面代码中注释掉的一行,因为我最初的想法是测试一个像素高的矩形,所以想当然地使用了Line,结果当然是不起作用了,从字面含义理解Region,当然是区域而非线条了。
- Winform自定义窗体与控件的外观形状
- 创建自定义形状的窗体和控件
- Shape 自定义控件的形状
- 教你创建自定义形状的窗体
- 画出各种自定义的窗体形状
- 自定义形状窗体
- 自定义形状窗体
- Winform下ToolStrip承载自定义控件或 Windows 窗体控件。
- c#有关winform的两个代码片段(多线程操作窗体控件与窗体淡入淡出效果)
- 创建任何自定义形状的控件
- Android自定义控件-不同形状的ImageView
- C# WinForm窗体及其控件的自适应
- WinForm窗体及其控件的自适应
- WinForm窗体及其控件的自适应
- C# WinForm窗体及其控件的自适应
- C# WinForm窗体及其控件的自适应
- C# WinForm窗体及其控件的自适应
- WinForm窗体及其控件的自适应
- javascript实现本地预览图片的代码
- 界面库选型——Qt
- MyBatis order by 动态参数时或使用Like查询时用$而不是#
- 代码生成那点事
- 为什么要用cerr
- Winform自定义窗体与控件的外观形状
- 你真想到了50岁还靠编程来养家糊口吗?
- 程序员识己路
- 三菱PLC分类及型号的基础知识
- Math类常用方法
- BufferedWriterDemo
- 谨以此文献给2013届正在找工作的同学们
- iOS 平台下写网络视频监视器中的总结
- sql 查询慢的48个原因分析。