栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

.net Winform绘制聊天窗口

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

.net Winform绘制聊天窗口

近期由于需要,使用.net绘制了一个聊天窗口的demo,支持阅后即焚,先看效果图:

 

聊天窗口支持文字、文件、图片、视频、语音、名片、语音通话(需要搭建SIP服务器)等功能,联系人支持拖拽弹出独立窗体。 整体界面是仿照微信进行绘制的,使用GDI+进行图形绘制。

聊天窗口是最复杂的部分,目前是基于原生的ListBox进行绘制的,如果大家有好的建议可以一起交流。因为使用ListBox进行绘制的,所以Item高度有一定的限制,不要超过255像素,超过了界面显示不完整,需要将界面拖放大点才能显示全,这个问题暂时还没想好怎么解决,有兴趣的朋友可以共同研究一下,以下是部分绘制的代码,起到抛砖引玉的作用,希望大家有更好的方案。

private void MesssageListBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (Items.Count == 0) return;

            int checkBoxWidth = 0;


            User user = (User)Items[e.Index];
            if (user == null) return;

            e.DrawBackground();
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            Brush pBlackBrush = Brushes.WhiteSmoke;
            if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
            {
                //e.DrawFocusRectangle();
                pBlackBrush = Brushes.LightGray;
            }
            Rectangle rectBg = e.Bounds;
            rectBg.Inflate(1, 1);
            e.Graphics.FillRectangle(pBlackBrush, rectBg);
            //e.Graphics.DrawString(this.listBox1.Items[e.Index].ToString(), this.listBox1.Font, Brushes.Black, e.Bounds); 

            // 鼠标划过效果
            if (e.Bounds.Contains(PointToClient(MousePosition)))
            {
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(150, Color.LightGray)), rectBg);
            }

            // 绘制头像
            Image face;
            if (user.IsChatRoom)
            {
                face = user.Face == null ? Resources.face_group : user.Face;
            }
            else
            {
                face = user.Face == null ? Resources.face_ui : user.Face;
            }
            e.Graphics.DrawImage(face, new RectangleF(e.Bounds.X + 10, e.Bounds.Y + 10, 40, 40));

            if (user.IsMessageUnRead)
            {
                // 模拟新消息提醒的红点,带阴影。
                Rectangle newRect = new Rectangle(e.Bounds.X + 46, e.Bounds.Y + 6, 10, 10);
                //e.Graphics.FillEllipse(new SolidBrush(Color.FromArgb(120, 0, 0, 0)), newRect);//绘制阴影
                newRect = new Rectangle(e.Bounds.X + 45, e.Bounds.Y + 5, 10, 10);
                e.Graphics.FillEllipse(Brushes.Red, newRect);
            }

            // 绘制姓名
            StringFormat _sf = new StringFormat();
            _sf.LineAlignment = StringAlignment.Center;
            _sf.Trimming = StringTrimming.EllipsisCharacter;
            Font font = new System.Drawing.Font("微软雅黑", 12);
            float fTop = (e.Bounds.Height - e.Font.Height) / 2;
            Rectangle Rect = new Rectangle(e.Bounds.X + 60, e.Bounds.Y + 10, e.Bounds.Width - 65 - checkBoxWidth, font.Height);
            e.Graphics.DrawString(user.Name, font, user.IsOnLine ? Brushes.Green : Brushes.Black, Rect, _sf);
            //e.Graphics.DrawRectangle(new Pen(Color.Red), Rect); //调试用矩形框

            StringFormat sf = new StringFormat();
            sf.Trimming = StringTrimming.EllipsisCharacter;
            sf.LineAlignment = StringAlignment.Center;

            // 绘制消息时间
            string time = user.LastTime.ToString("HH:mm");
            SizeF timeSize = e.Graphics.MeasureString(time, Font);
            Rectangle rectTime = new Rectangle(e.Bounds.Width - (int)timeSize.Width - 4,
                e.Bounds.Y + 36, (int)timeSize.Width + 1, e.Font.Height);
            if (!string.IsNullOrEmpty(user.LastMessage))
            {
                // 当最后信息不为空时才绘制时间信息
                e.Graphics.DrawString(time, Font, Brushes.Gray, rectTime, sf);
            }

            // 绘制消息
            Rectangle Rect1 = new Rectangle(e.Bounds.X + 60, e.Bounds.Y + 36,
                e.Bounds.Width - rectTime.Width - 66, e.Font.Height);
            e.Graphics.DrawString(user.LastMessage, Font, Brushes.Gray, Rect1, sf);
        }

在绘制过程中,重载了两个方法,MeasureItem和DrawItem,MeasureItem用于计算消息框的高度,DrawItem负责具体的绘制,在绘制过程中需要注意是发送的消息还是收到的消息。表情动画使用ImageAnimator进行动画分解与绘制,动画过多的要注意防止屏闪,尽量开启双缓冲绘图,能有效的减少屏闪。

拖拽联系人的效果比较简单,只要绘制一个光标替换当前的光标就行了,等拖拽完成后再恢复光标到默认即可。

由于是demo,以研究性为主,很多功能暂时还未实现,基本的单聊、群聊都实现了,支持群发文件、视频、语音、图片等,暂不支持语音群聊,只能语音一对一通话,也没有视频通话,后期完善后再来补充文档与代码。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/909618.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号