标签:size 思考 get round 函数 微软雅黑 int code 开始
一、说明
1、一般在录入界面做验证提醒都是弹出messagebox,但是美观和体验都不好,所以想到了这个。网上有很多例子,但是作为小白,想自己写一下,加深理解。
2、没有做成自定义控件,只是简单的实现了一下原理,可以继续完善。
二、效果
三、实现
实现原理:首先提示用到画图:提示框为一个三角形+圆角矩形+文字;然后就是各种参数计算位置。
1、定一个公共的画验证提示内容的类,具体代码如下,都有注释
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; namespace Mandala.HIS.Components.Triage { class GraphicMsg { #region 定义画图公共参数 //定义提醒内容的字体、颜色、背景色。 private static Font MsgFont = new Font("微软雅黑", 4F, GraphicsUnit.Millimeter); private static Color msgBackColor = Color.Tomato; private static Color msgFontColor = Color.White; //提示内容矩形高度 private static int RectH = 26; //三角形的高 private static int TriH = 20; private static int r = 1;//圆角半径,同时用于矩形的起始点x的偏移 #endregion /// <summary> /// 根据提醒内容计算提醒框长度 /// </summary> /// <param name="g">Graphics 对象</param> /// <param name="strMsg">提醒内容</param> /// <param name="rectangle">控件的位置:起始,长宽</param> public static int GetStrMsgLength(string strMsg) { int MsgLength = 0; MsgLength =2 + strMsg.Length * 15; return MsgLength; } /// <summary> /// 绘制提醒内容 /// </summary> /// <param name="g">Graphics 对象</param> /// <param name="strMsg">提醒内容</param> /// <param name="rectangle">控件的位置:起始,长宽</param> public static void DrawStr(Graphics g,string strMsg, Rectangle rectangle) { rectangle.X = rectangle.X + rectangle.Width + TriH - r-2; rectangle.Y = rectangle.Y - (RectH - rectangle.Height) / 2; SolidBrush drawBush = new SolidBrush(msgFontColor); g.DrawString(strMsg, MsgFont, drawBush, rectangle.X, rectangle.Y + 2); } /// <summary> /// GDI+ 绘制实心三角形 /// </summary> /// <param name="g">Graphics 对象</param> /// <param name="rectangle">控件的位置:起始,长宽</param> public static void DrawTriangle(Graphics g, Rectangle rectangle) { int H = TriH; int P1x = rectangle.X + rectangle.Width; int P1y = rectangle.Y + (rectangle.Height / 2); int P2x = rectangle.X + rectangle.Width + H; int P2y = rectangle.Y; int P3x = rectangle.X + rectangle.Width + H; int P3y = rectangle.Y + rectangle.Height; Point point1 = new Point(P1x, P1y); Point point2 = new Point(P2x, P2y); Point point3 = new Point(P3x, P3y); Point[] pntArr = { point1, point2, point3 }; Brush myBrushes = new SolidBrush(msgBackColor); g.FillPolygon(myBrushes, pntArr); } /// <summary> /// C# GDI+ 绘制圆角实心矩形 /// </summary> /// <param name="g">Graphics 对象</param> /// <param name="rectangle">要填充的矩形</param> /// <param name="strMsg">提醒内容,用于计算需要的矩形长度</param> public static void FillRoundRectangle(Graphics g, Rectangle rectangle,string strMsg) { //根据字体计算矩形宽度,5为偏移常量,为了美观 //重新计算矩形的rectangle,使它始终按照自己的高度显示在控件水平中间 int H = TriH; rectangle.X = rectangle.X + rectangle.Width + H - r - 5; rectangle.Y = rectangle.Y - (RectH-rectangle.Height)/2; rectangle.Width = GetStrMsgLength(strMsg); rectangle.Height = RectH; rectangle = new Rectangle(rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1); Brush b = new SolidBrush(msgBackColor); g.FillPath(b, GetRoundRectangle(rectangle, r)); } /// <summary> /// 根据普通矩形得到圆角矩形的路径 /// </summary> /// <param name="rectangle">原始矩形</param> /// <param name="r">半径</param> /// <returns>图形路径</returns> private static GraphicsPath GetRoundRectangle(Rectangle rectangle, int r) { int l = 2 * r; // 把圆角矩形分成八段直线、弧的组合,依次加到路径中 GraphicsPath gp = new GraphicsPath(); gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y)); gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F); gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r)); gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F); gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom + 1), new Point(rectangle.X + r, rectangle.Bottom + 1)); gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F); gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r)); gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F); return gp; } } }
2、调用示例
//初始化提醒内容。 string strMsg = "不能为空!"; Graphics g = this.CreateGraphics(); //初始化Rectangle,获取验证控件的坐标和大小 Rectangle myRect = new Rectangle(); myRect.Location = this.mtlTextBox1.Location; myRect.Size = this.mtlTextBox1.Size; //绘制三角形: GraphicMsg.DrawTriangle(g, myRect); //圆角矩形,初始化Rectangle GraphicMsg.FillRoundRectangle(g, myRect,strMsg); //写字 GraphicMsg.DrawStr(g, strMsg, myRect);
四、思考
1、一开始考虑将所有能控制的都作为参数,可以自己定义,但是后来反复实验还是目前这样的参数设置比较美观,所以把一些基础参数放到了GraphicMsg类里面定义了,需要的可以自己改。
2、字体大小和提示内容的宽度息息相关,我这里固定了一个字体,所以宽度计算固定为GetStrMsgLength里面的方法(如果字体改大,这个函数要调整),也可以另一种方法:定义一个隐藏的标签,把字体和内容放到标签中,然后获取标签的长度用于绘制矩形的长度,这样比较灵活,但是我不想界面上有个没有实际意义的标签(原谅我的强迫症!),其他好的方案暂时没想到。
3、目前仅仅是简单实现了在控件右侧提醒,如果控件在最右边,提醒内容会被覆盖,可以增加属性控制,让其在控件的上下左右都可以,自定义选择,当然代码也要相应扩展。
标签:size 思考 get round 函数 微软雅黑 int code 开始
原文地址:https://www.cnblogs.com/infimymskeen/p/12382264.html