吵吵   2015-08-30  阅读:3,260

说到IM工具呢,我是没有心情用QQ的,实在是太臃肿了,自从微信出来之后,我都宁愿用微信的电脑版。

我依旧喜欢简洁的东西。

因此,即便是仿一个聊天界面出来,我也愿意仿微信的,而不是QQ。

微信气泡聊天

c#怎么实现微信的气泡聊天?自己手动去画控件就好了,涉及到的技术细节,我觉得还是可以讲一下的:

1、气泡聊天框是怎么画的?

这个其实蛮简单的,画一个圆角矩形,再加上一个三角形就OK了。圆角矩形在C#里面是画四段圆弧,然后闭合形成的,至于三角形么,Graphic本身就有这个函数。

我观察了一下手机微信上的气泡,发现侧边的其实并不是一个三角形,虽然它长的像是三角形,但是那不是个尖尖,而是一段圆弧!我已然是没有心情再去处理这个细节,但是人家真的是花了大心思的,不得不佩服。

2、带滚动条的控件是怎么回事?

如果是普通的图形控件,我们重载OnPaint控件直接去画就行了,但是如果画的内容已经超过了控件的高度,我们需要滚动条的时候怎么办呢?

一种思路是,我们设想有这样一个容器,这个容器带滚动条,叫做SrollBox,往里面加的项目都应该实现一个Paint()的接口,那么ScorllBox将调用这个接口来进行绘图。

另一种思路是,我们的控件就是WXChatBox,如果控件中的内容超过了控件的高度的话,我们就new一个Sroll,并且订阅Sroll的滚动事件,如果有滚动的话,我们就重绘内容。

不管是哪一种思路,都需要解决一个问题,就是如果滚动条卷去了一部分内容,我们该如何画起?例如整个控件的高度是200,内容是400,如果滚动条滚动到了50,那么我应该是从内容的50的部分画起的,一直画到250结束的。好了问题就来了,例如第一个微信气泡高度是30,第二个高度是40,如果我从50的高度开始画的话,我等于是画半个第二个气泡。如果话一个圆角矩形是一个函数DrawRectangle,我是没有办法从中间开始画的。

走入了思考的死胡同,我们就会去思考另外一个办法。如果我没有办法去画一个一半的杯子,那么我是否可以画一个完整的,只是遮罩掉上半部分呢?确实是这么做的,还是上面的例子,我可以从-50开始画,事实上我是从-20开始画第二个气泡的,只是-20的都被遮住了,我就只看到了一个一半的气泡!

用负值的方法去绘图是一种方法,其实c#的graphic已经提供了一个位移的函数:

Graphics g = pe.Graphics;
if (verticalScroll != null)
{
g.TranslateTransform(0, -verticalScroll.Value);
}
减去滚动条的高度,就是我们绘图的开始,从上到下慢慢绘吧,即使很大部分都是看不到的!

3、字体的高度是怎么计算的?

计算一个气泡的高度的时候,如果是文件或者图片的话,这个高度是固定的,但是如果是文字呢?这就麻烦了,到底多少字算的上一行,字符之间的间距是多少,行间距是多少,如果要计算高度和宽度,中文和英文,以及标点又分别占多宽?

告诉你,如果你这么去计算的话,又错了。

因为绘制的字体像素,甚至是屏幕的不同,都不一样的,那怎么办呢?

private int GetStringHeight(Graphics g,string text, int width)
{

Font font = new Font(“微软雅黑”, 14);
SizeF size= g.MeasureString(text, font,width);

return (int)size.Height;
}
好在是有一个MeasureString的函数,可以根据你给的宽度来计算字体有多高。

这终于解决了一个头疼的问题,只是为什么它会无缘无故的截断一些字体呢,没有换行也会,至今没有找到答案。

效果最终如何,你看图就行了,图片上的文字有几个绘制歪了,我会调整一下的。

吵吵微信朋友圈,请付款实名加入:

吵吵 吵吵

2条回应:“c#仿微信气泡聊天控件”

  1. helloWorld说道:

    正在学习这一块,求源码,能发一份吗?eennddyy@126.com

发表评论

电子邮件地址不会被公开。 必填项已用*标注