前两天的《C#实现微信聊天对话框》大师给了不少的好的建议,本文基于进步并进行了改进,望大师一路来评论辩论~~~
之前靠山的边框采取靠山图片的体式格式,今朝已采取GDI+直接绘制的体式格式,并且添加了靠山色以增长用户体验~~
具本的代码如下:
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 }

596

被折叠的 条评论
为什么被折叠?



