跟我做WinForm开发1 winform通用开发框架

前言

前阵子,学英文的时候听发音,意外之中发现Google的发音相比大部分TTS发音更准确,而且读句子也没有普通TTS那种一听就是机器人的声音,心血来潮,想利用Google发音做一个小软件,所以就有了本文。



这是最后的UI成品图,可以看到,没有了常见的按钮,也没有了常见的Title框,整个布局随心所欲,GDI+?No。下面,就带大家跟我一起来用最简单的方式开发你所期望的UI吧!

自定义窗体

WinForm开发中,我们都知道窗体和控件的作用,实际上,以上的UI实现也是通过自定义窗体和用户控件实现,那该如何做,才能让窗体变成我们所想要的样子呢?

首先,新建一个窗体,在这里,我命名为MainForm.cs,打开我们就可以见到以往的样子:



选中窗体,右键=》属性,将FormBorderStyle设置成None, 窗体就变成了右图所示;接着,我再将其拖拉成我需要的长度和宽度,此时若编译运行,会发现实际上什么都东西都看不到,这正是我们所需要的效果,接着,就防止我们想呈现的元素。接着,我将其拉成一个长方形,并在四周放4个PictureBox,正中间放一个Panel。
跟我做WinForm开发(1) winform通用开发框架



这里需要注意的就是4个PictureBox的宽度,长度和未知,实际上我也不是拖控件,而是通过修改控件是属性,这里就需要精确到像素,聪明的你应该想到它们就是4条边框线和中间的内容块了,在这里我推荐一个软件,MarkMan,传说中的标注神器,做UI方面,特别是开发人员,很有帮助。



在将所需的图片填充上去就可以了。

private Image GetResourceImg(string name){ return Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(name));}void InitFormStyle(){ //边框 var borderImg = GetResourceImg(@"Speaker.Resource.Images.border.jpg"); Bitmap borderMap = new Bitmap(borderImg); borderMap.MakeTransparent(Color.FromArgb(255, 0, 255)); this.pb_borderLeft.BackgroundImage = borderMap; this.pb_borderRight.BackgroundImage = borderMap; this.pb_borderTop.BackgroundImage = borderMap; this.pb_borderBottom.BackgroundImage = borderMap; //主面板 var mainImg = GetResourceImg(@"Speaker.Resource.Images.main.jpg"); this.pl_main.BackgroundImage = new Bitmap(mainImg); //Logo var logoImg = GetResourceImg(@"Speaker.Resource.Images.logo.jpg"); this.btn_setting.NormalImage = new Bitmap(logoImg); btn_setting.Reset(); //Speak Button var normalImg = GetResourceImg(@"Speaker.Resource.Images.button.png"); var moveImg = GetResourceImg(@"Speaker.Resource.Images.buttonMove.png"); var downImg = GetResourceImg(@"Speaker.Resource.Images.buttonDown.png"); btn_speak.NormalImage = normalImg; btn_speak.MoveImage = moveImg; btn_speak.DownImage = downImg; btn_speak.Reset();}

编译通过之后,边框雏形就出现了~:-)

自定义控件

窗体我们已经有了,接下来就是里面一些控件的实现,这里,我主要用到了两个控件,ImageButton和LightTextBox,顾名思义,ImageButton就是一个图片按钮,但它还提供鼠标按下,悬移时的图片选择;LightTextBox是一个TextBox,鼠标悬移的时候,边框高亮;

LightTextBox

新建用户控件LightTextBox,选中控件,右键=》属性,将BorderStyle改为None,这样,控件也不可见了!拖出一个TextBox,并标注为MultiLine,至此,UI就这样了,接着是控件的绘制编码;

public LightTextBox(){ SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); InitializeComponent(); BackColor = Color.Transparent; txt.Location = new Point(3, 6); txt.MouseEnter += new EventHandler(txt_MouseEnter); txt.MouseLeave += new EventHandler(txt_MouseLeave);}

实现TextBox的鼠标悬移事件就是为了实现边框高亮效果;

#region Eventsvoid txt_MouseLeave(object sender, EventArgs e){ _isFouse = false; this.Invalidate();}void txt_MouseEnter(object sender, EventArgs e){ _isFouse = true; this.Invalidate();}#endregion

方法部分(控件实现的主要方法)

#region Methodsprotected override void OnPaint(PaintEventArgs e){ Graphics g = e.Graphics; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; txt.Width = Width-6; CalculateSizeAndPosition(); Draw(e.ClipRectangle, e.Graphics); base.OnPaint(e);}private void CalculateSizeAndPosition(){ if (!txt.Multiline) { Height = txt.Height + 9; } else { txt.Height = Height - 9; }}private void Draw(Rectangle rectangle, Graphics g){ #region 画背景 using (SolidBrush backgroundBrush = new SolidBrush(Color.White)) { g.FillRectangle(backgroundBrush, 2, 2, this.Width - 4, this.Height - 4); } #endregion #region 画阴影(外边框) Color drawShadowColor = _shadowColor; if (!_isFouse) //判断是否获得焦点 { drawShadowColor = Color.Transparent; } using (Pen shadowPen = new Pen(drawShadowColor)) { if (_radius == 0) { g.DrawRectangle(shadowPen, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1)); } else { g.DrawPath(shadowPen, DrawHelper.DrawRoundRect(rectangle.X, rectangle.Y, rectangle.Width - 2, rectangle.Height - 1, _radius)); } } #endregion #region 画边框 using (Pen borderPen = new Pen(_borderColor)) { if (_radius == 0) { g.DrawRectangle(borderPen, new Rectangle(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 3)); } else { g.DrawPath(borderPen, DrawHelper.DrawRoundRect(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 2, _radius)); } } #endregion}#endregion

由于字段,属性比较多,我就不贴出来了,感兴趣的可以在后续的源码中查看;此时,若将该控件放到窗体中,鼠标移

动上去,则可发现边框有一层光晕;

ImageButton

这里的自定义控件实现方式一致,都先去掉了BorderStyle,再自己控制呈现内容,所以才能达到显示特殊UI的目的;ImageButton的UI设计就不详述了,直接放出后台实现主代码;

public ImageButton(){ this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); InitializeComponent(); Reset();}#region Methodspublic void Reset(){ if (_normalImage != null) { this.BackgroundImage = _normalImage; this.Size = new Size(_normalImage.Width, _normalImage.Height); }}private void MakeTransparent(Image image){ Bitmap bitmap = image as Bitmap; bitmap.MakeTransparent(Color.FromArgb(255, 0, 255));}#endregionprivate void ImageButton_MouseEnter(object sender, EventArgs e){ if (_moveImage != null) this.BackgroundImage = _moveImage;}private void ImageButton_MouseLeave(object sender, EventArgs e){ this.BackgroundImage = _normalImage;}private void ImageButton_MouseDown(object sender, MouseEventArgs e){ if (_downImage != null) this.BackgroundImage = _downImage;}private void ImageButton_MouseUp(object sender, MouseEventArgs e){ if (_moveImage != null) this.BackgroundImage = _moveImage;}MainForm

万事俱备,只欠东风;把控件都放入MainForm中,并初始其状态即可(上面第一部分代码已放出);此时,编译运行;已达到我们预期的UI效果;但是,UI效果是有了,移动效果,缩小(点击任务栏图标)等却都失效了,该怎么办?Win32API千呼万唤使出来~

private void pl_main_MouseDown(object sender, MouseEventArgs e){ if (e.Button == MouseButtons.Left) { Win32.ReleaseCapture(); Win32.SendMessage(Handle, 274, 61440 + 9, 0); }}

这里实际上是调用了Win32API,在这里,又有一个好东西分享;平时做这些Win32API交互/C#与C++交互,需

要做类型转换,特别是C++里面一些指针什么的,很是纠结,http://clrinterop.codeplex.com能帮到你;它能根据你输入的C++函数生成C#的代码;不可谓不是一大杀器啊!

移动解决了,那缩小的问题,也必须解决了;

protected override CreateParams CreateParams{ get { const int WS_MINIMIZEBOX = 0x00020000; // Winuser.h中定义 CreateParams cp = base.CreateParams; cp.Style = cp.Style | WS_MINIMIZEBOX; // 允许最小化操作 return cp; }}

重写CreateParams属性就可以了;到这里,我们的应用已经能正常显示出我们所想要的UI;但还不够,大部

分辅助类型的软件都有最小化的功能,那,我们也将其加上去吧;

NotifyIcon

这个其实很简单,就是拖一个NotifyIcon到窗体中,并绑定一个ContextMenu到这个NotifyIcon中就可以了;然后在触发一些事件;

private void MainForm_Resize(object sender, EventArgs e){ if (WindowState == FormWindowState.Minimized) { this.Visible = false; }}

后面,我还主要用NotifyIcon来通知用户,做提示,错误提示等;到这里,整个UI方面就已经完成了;只

剩下后面的逻辑处理,就是输入句子能发音,并且支持快捷键屏幕取词等;

参考资料

跟我学做c#皮肤美化

WinAPI使用大全

作者:空逸云

出处:http://kongyiyun.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  

爱华网本文地址 » http://www.aihuau.com/a/25101011/87772.html

更多阅读

教育教学论坛75 爱护公物爱护环境从我做起 爱护公物手抄报

爱护公物爱护环境从我做起良好的社会公德,是社会文明的标志,是民族高素质的体现,是精神文明建设的重要内容。小学生是祖国的未来,跨世纪的建设者。小学生的健康成长是祖国前途和民族命运的大事,尤其是在新旧体制转变过程中,如果不认真的

我做的玉米面粥 南瓜玉米面粥的做法

我做的玉米面粥现在,人们的生活水平提高了,不像上世纪五、六十年代那样为吃、穿发愁了。可话又说回来,那个时候能不发愁吗?吃的是低标准、瓜菜代,买粮要粮票,买布做衣服要布票,离了这票那票的,您是寸步难行。时间早已进入了二十一世纪,改革

鱿鱼怎么清洗怎么做好吃:1 处理鱿鱼

鱿鱼怎么清洗怎么做好吃:[1]处理鱿鱼——简介 鱿鱼含有丰富的蛋白质,及人体所必须的氨基酸,大量的牛磺酸,大量的胆固醇,钙、磷、硒、钾、钠等微量元素含量高,能防治贫血,降低血液中的胆固醇,缓解疲劳,还能预防糖尿病 忌口:痛风患者不宜食用,脾

声明:《跟我做WinForm开发1 winform通用开发框架》为网友花依赖叶子分享!如侵犯到您的合法权益请联系我们删除