前两天的《C#实现微信聊天对话框》大家给了不少的好的建议,本文基于前进文进行了改进,望大家一起来讨论~~~
先看一下改进后的界面效果:
之前背景的边框采用背景图片的方式,目前已采用GDI+直接绘制的方式,并且添加了背景色以增加用户体验~~
具本的代码如下:
View Code
1 using System; 2 using System.ComponentModel; 3 using System.Drawing; 4 using System.Drawing.Drawing2D; 5 using System.Windows.Forms; 6 7 namespace Sun.WinFormControl 8 { 9 /// <summary> 10 /// 类似微信的聊天对话框。 11 /// </summary> 12 /// <remarks> 13 /// Author:SunYujing 14 /// DateTime:2012-07-19 15 /// </remarks> 16 public class WxChartBox : Control 17 { 18 /// <summary> 19 /// 构造方法。 20 /// </summary> 21 public WxChartBox() 22 { 23 SetStyle(ControlStyles.DoubleBuffer, true); //双缓冲防止重绘时闪烁 24 SetStyle(ControlStyles.AllPaintingInWmPaint, true); //忽略 WM_ERASEBKGND 窗口消息减少闪烁 25 SetStyle(ControlStyles.UserPaint, true); //自定义绘制控件内容 26 SetStyle(ControlStyles.SupportsTransparentBackColor, true); //模拟透明 27 SetStyle(ControlStyles.Selectable, false); //接收焦点 28 Size = new Size(500, 60); //初始大小 29 Font = new Font("微软雅黑", 10); 30 } 31 /// <summary> 32 /// 用户名。 33 /// </summary> 34 private string _username = "用户名"; 35 /// <summary> 36 /// 消息日期时间。 37 /// </summary> 38 private DateTime _messagetime = DateTime.Now; 39 /// <summary> 40 /// 消息内容。 41 /// </summary> 42 private string _messagecontent = "消息内容"; 43 /// <summary> 44 /// 每行消息数据的字节数。 45 /// </summary> 46 //private int _perlinebit = 68; 47 /// <summary> 48 /// 每行字符数。 49 /// </summary> 50 private int _perlinechar = 35; 51 /// <summary> 52 /// 消息内容的行高。 53 /// </summary> 54 private int _lineheight = 22; 55 /// <summary> 56 /// 背景图高。 57 /// </summary> 58 private int _iheight = 8; 59 /// <summary> 60 /// 背景图宽。 61 /// </summary> 62 private int _iwidth = 8; 63 /// <summary> 64 /// 消息类型。 65 /// </summary> 66 private MessageType _messagetype = MessageType.Receive; 67 /// <summary> 68 /// 获取或设置用户名。 69 /// </summary> 70 [Description("获取或设置用户名。")] 71 public string UserName 72 { 73 get 74 { 75 return _username; 76 } 77 set 78 { 79 _username = value; 80 Invalidate(false); 81 } 82 } 83 84 /// <summary> 85 /// 获取或设置用户名。 86 /// </summary> 87 [Description("获取或设置用户名。")] 88 public DateTime MessageTime 89 { 90 get 91 { 92 return _messagetime; 93 } 94 set 95 { 96 _messagetime = value; 97 Invalidate(false); 98 } 99 } 100 101 /// <summary> 102 /// 获取或设置消息内容。 103 /// </summary> 104 [Description("获取或设置消息内容。")] 105 public string MessageContent 106 { 107 get 108 { 109 return _messagecontent; 110 } 111 set 112 { 113 _messagecontent = value; 114 Invalidate(false); 115 } 116 } 117 118 /// <summary> 119 /// 获取或设置消息的类型。 120 /// </summary> 121 [Description("获取或设置消息的类型。")] 122 public MessageType MType 123 { 124 get 125 { 126 return _messagetype; 127 } 128 set 129 { 130 _messagetype = value; 131 Invalidate(false); 132 } 133 } 134 /// <summary> 135 /// 自定义绘制。 136 /// </summary> 137 protected override void OnPaint(PaintEventArgs e) 138 { 139 base.OnPaint(e); 140 Graphics g = e.Graphics; 141 g.SmoothingMode = SmoothingMode.HighQuality; 142 g.PixelOffsetMode = PixelOffsetMode.HighQuality; 143 Size = new Size(500, InitHeight()); 144 DrawBackColor(g); 145 DrawBackGroundLine(g); 146 DrawText(g); 147 DrawLine(g); 148 DrawMessageContent(g); 149 } 150 /// <summary> 151 /// 绘制用户名和消息时间。 152 /// </summary> 153 private void DrawText(Graphics g) 154 { 155 Font f = new Font("微软雅黑", 10,FontStyle.Bold); 156 g.DrawString(UserName+" "+MessageTime.ToString("yyyy-MM-dd HH:mm:ss"), f, new SolidBrush(ForeColor), 8+_iwidth, 2); 157 } 158 /// <summary> 159 /// 绘制一条直线。 160 /// </summary> 161 private void DrawLine(Graphics g) 162 { 163 Color color = Color.Green; 164 if(MType==MessageType.Receive) 165 color = Color.Red; 166 Pen p = new Pen(color); 167 p.Width = 1; 168 g.DrawLine(p, 4 + _iwidth, 22, Width - 8 - _iwidth , 22); 169 } 170 /// <summary> 171 /// 绘制短信内容。 172 /// </summary> 173 private void DrawMessageContent(Graphics g) 174 { 175 int initheight = 22; 176 int rowscount = MessageLineCount(); 177 string contents = MessageContent; 178 string content = ""; 179 for (int i = 0; i < rowscount; i++) 180 { 181 if (contents.Length > _perlinechar) 182 { 183 content = contents.Substring(0, _perlinechar); 184 contents = contents.Remove(0, _perlinechar); 185 } 186 else 187 { 188 content = contents; 189 } 190 g.DrawString(content, Font, new SolidBrush(ForeColor), 4+_iwidth, initheight + i * _lineheight); 191 } 192 } 193 /// <summary> 194 /// 绘制边框。 195 /// </summary> 196 private void DrawBackGroundLine(Graphics g) 197 { 198 Pen p = new Pen(Color.Black); 199 p.Width = 1; 200 g.DrawArc(p, _iwidth, 0, _iwidth, _iheight, 180, 90); 201 g.DrawLine(p, (int)(_iwidth * 1.5), 0, Width - (int)(_iwidth * 1.5), 0); 202 g.DrawArc(p, Width - _iwidth * 2, 0, _iwidth, _iheight, 270, 90); 203 if (MType == MessageType.Send) 204 { 205 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 0.5), Width - _iwidth, (int)(_iheight * 1.5)); 206 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 1.5), Width, _iheight * 2); 207 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 2.5), Width, _iheight * 2); 208 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 2.5), Width - _iwidth, Height - (int)(_iheight * 0.5)); 209 } 210 else 211 { 212 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 0.5), Width - _iwidth, Height - (int)(_iheight * 0.5)); 213 } 214 g.DrawArc(p, Width - _iwidth * 2, Height - _iheight,_iwidth,_iheight, 0, 90); 215 g.DrawLine(p, (int)(_iwidth * 1.5), Height, Width - (int)(_iwidth * 1.5), Height); 216 g.DrawArc(p, _iwidth, Height - _iheight, _iwidth, _iheight, 90, 90); 217 if (MType == MessageType.Receive) 218 { 219 g.DrawLine(p, _iwidth, (int)(_iheight * 0.5), _iwidth, (int)(_iheight * 1.5)); 220 g.DrawLine(p, 0, _iheight * 2, _iwidth, (int)(_iheight * 1.5)); 221 g.DrawLine(p, 0, _iheight * 2, _iwidth, (int)(_iheight * 2.5)); 222 g.DrawLine(p, _iwidth, (int)(_iheight * 2.5), _iwidth, Height - (int)(_iheight * 0.5)); 223 } 224 else 225 { 226 g.DrawLine(p, _iwidth, (int)(_iheight * 0.5), _iwidth, Height - (int)(_iheight * 0.5)); 227 } 228 } 229 /// <summary> 230 /// 绘制背景色。 231 /// </summary> 232 private void DrawBackColor(Graphics g) 233 { 234 Brush b = Brushes.YellowGreen; 235 Point[] ps = new Point[3]; 236 if (MType == MessageType.Receive) 237 { 238 ps[0] = new Point(0, _iheight * 2); 239 ps[1] = new Point(_iwidth, (int)(_iheight * 1.5)); 240 ps[2] = new Point(_iwidth, (int)(_iheight * 2.5)); 241 } 242 else 243 { 244 b = Brushes.Goldenrod; 245 ps[0] = new Point(Width - _iwidth, (int)(_iheight * 1.5)); 246 ps[1] = new Point(Width - _iwidth, (int)(_iheight * 2.5)); 247 ps[2] = new Point(Width, _iheight * 2); 248 } 249 g.FillEllipse(b, _iwidth, 0, _iwidth, _iheight); 250 g.FillEllipse(b, Width - _iwidth * 2, 0, _iwidth, _iheight); 251 g.FillEllipse(b, Width - _iwidth * 2, Height-_iheight, _iwidth, _iheight); 252 g.FillEllipse(b, _iwidth, Height - _iheight, _iwidth, _iheight); 253 g.FillRectangle(b, _iwidth, (int)(_iheight*0.5), Width - _iwidth * 2, Height - _iheight); 254 g.FillRectangle(b, (int)(_iwidth * 1.5), 0, Width - _iwidth * 3, (int)(_iheight * 0.5)); 255 g.FillRectangle(b, (int)(_iwidth * 1.5), Height - (int)(_iheight * 0.5), Width - _iwidth * 3, (int)(_iheight * 0.5)); 256 g.FillPolygon(b, ps); 257 } 258 /// <summary> 259 /// 动态计算控件高度。 260 /// </summary> 261 /// <returns>控件高度。</returns> 262 public int InitHeight() 263 { 264 int rowCount = MessageLineCount(); 265 int iRows = rowCount == 0 ? 1 : rowCount; 266 return iRows * _lineheight + 22; 267 } 268 /// <summary> 269 /// 获取消息行数。 270 /// </summary> 271 /// <returns>消息行数。</returns> 272 private int MessageLineCount() 273 { 274 //int MessageBits = Encoding.Default.GetByteCount(MessageContent.Trim()); 275 //return (int)Math.Ceiling(MessageBits * 1.0 / _perlinebit); 276 int MessageCharCount = MessageContent.Trim().Length; 277 return (int)Math.Ceiling(MessageCharCount * 1.0 / _perlinechar); 278 } 279 } 280 281 /// <summary> 282 /// 消息类型。 283 /// </summary> 284 public enum MessageType 285 { 286 /// <summary> 287 /// 发送消息。 288 /// </summary> 289 Send, 290 /// <summary> 291 /// 接收消息。 292 /// </summary> 293 Receive 294 } 295 }
欢迎有兴趣的园友一起讨论学习~~~