最近喜欢上了玩微信,觉得微信的了聊天对话框挺不错的,于是自己也使用C#实现了一个类似的控件,代码如下:
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 = 34; 51 /// <summary> 52 /// 消息内容的行高。 53 /// </summary> 54 private int _lineheight = 22; 55 /// <summary> 56 /// 背景图高。 57 /// </summary> 58 private int _imageheight = 8; 59 /// <summary> 60 /// 背景图宽。 61 /// </summary> 62 private int _imagewidth = 8; 63 /// <summary> 64 /// 消息类型。 65 /// </summary> 66 private MessageType _messagetype = MessageType.Reseave; 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 Width = 500; 144 Height = InitHeight(); 145 DrawImage(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+_imagewidth, 2); 157 } 158 159 /// <summary> 160 /// 绘制一条直线。 161 /// </summary> 162 private void DrawLine(Graphics g) 163 { 164 Color color = Color.Green; 165 if(MType==MessageType.Reseave) 166 color = Color.Red; 167 Pen p = new Pen(color); 168 p.Width = 1; 169 g.DrawLine(p, 4 + _imagewidth, 22, Width - 8 - _imagewidth , 22); 170 } 171 /// <summary> 172 /// 绘制短信内容。 173 /// </summary> 174 private void DrawMessageContent(Graphics g) 175 { 176 int initheight = 22; 177 int rowscount = MessageLineCount(); 178 string contents = MessageContent; 179 string content = ""; 180 for (int i = 0; i < rowscount; i++) 181 { 182 if (contents.Length > _perlinechar) 183 { 184 content = contents.Substring(0, _perlinechar); 185 contents = contents.Remove(0, _perlinechar); 186 } 187 else 188 { 189 content = contents; 190 } 191 g.DrawString(content, Font, new SolidBrush(ForeColor), 4+_imagewidth, initheight + i * _lineheight); 192 } 193 } 194 /// <summary> 195 /// 绘制背景图片。 196 /// </summary> 197 /// <param name="g"></param> 198 private void DrawImage(Graphics g) 199 { 200 //绘制左上角背景图 201 g.DrawImage(Properties.Resources.ZSJ, _imagewidth, 0); 202 //绘制上边框 203 g.DrawImage(Properties.Resources.HS, _imagewidth * 2, 0, Width - _imagewidth * 4, _imageheight); 204 //绘制右上角背景图 205 g.DrawImage(Properties.Resources.YHJ, Width - _imagewidth * 2-3, 0); 206 //绘制右边框 207 if (MType == MessageType.Send) 208 { 209 g.DrawImage(Properties.Resources.Y, Width - _imagewidth-1, _imageheight+1); 210 g.DrawImage(Properties.Resources.SY, Width - _imagewidth * 2, _imageheight * 2+2, _imagewidth, Height - _imageheight * 3-2); 211 } 212 else 213 { 214 g.DrawImage(Properties.Resources.SY, Width - _imagewidth * 2, _imageheight, _imagewidth, Height - _imageheight * 2); 215 } 216 //绘制右下角背景图 217 g.DrawImage(Properties.Resources.YXJ, Width - _imagewidth * 2 - 3, Height - _imageheight-2); 218 //绘制下边框 219 g.DrawImage(Properties.Resources.HX, _imagewidth * 2, Height - _imageheight, Width - _imagewidth * 4, _imageheight); 220 //绘制左下角背景图 221 g.DrawImage(Properties.Resources.ZXJ, _imagewidth, Height - _imageheight-2); 222 //绘制左边框 223 if (MType == MessageType.Reseave) 224 { 225 g.DrawImage(Properties.Resources.Z, 0, _imageheight+1); 226 g.DrawImage(Properties.Resources.SZ, _imagewidth, _imageheight * 2+2, _imagewidth, Height - _imageheight * 3-2); 227 } 228 else 229 { 230 g.DrawImage(Properties.Resources.SZ, _imagewidth, _imageheight, _imagewidth, Height - _imageheight * 2); 231 } 232 } 233 /// <summary> 234 /// 动态计算控件高度。 235 /// </summary> 236 /// <returns>控件高度。</returns> 237 public int InitHeight() 238 { 239 if(MessageLineCount()<2) 240 return 2 * _lineheight + 22; 241 else 242 return MessageLineCount() * _lineheight + 22; 243 } 244 /// <summary> 245 /// 获取消息行数。 246 /// </summary> 247 /// <returns>消息行数。</returns> 248 private int MessageLineCount() 249 { 250 int MessageBits = System.Text.Encoding.Default.GetByteCount(MessageContent.Trim()); 251 return (int)Math.Ceiling(MessageBits * 1.0 / _perlinebit); 252 } 253 } 254 255 /// <summary> 256 /// 消息类型。 257 /// </summary> 258 public enum MessageType 259 { 260 /// <summary> 261 /// 发送消息。 262 /// </summary> 263 Send, 264 /// <summary> 265 /// 接收消息。 266 /// </summary> 267 Reseave 268 } 269 }
最终实现结果如图:
资源文件中的图片文件下载:http://files.cnblogs.com/sunyujing/%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E5%9B%BE%E7%89%87.rar