C#实现微信聊天对话框的改进

时间:2024-03-08 19:50:48

 

前两天的《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 }

欢迎有兴趣的园友一起讨论学习~~~