WPF下聊天气泡的实现

零、版本履历

日期 说明
2020.05.02 初稿

一、效果

先看最终效果。

WPF下聊天气泡的实现_第1张图片

最终微聊烂尾了,更确切地说,还没开始就结束了。

二、由来

产品虽然没有最终做出来,但至少聊天气泡打磨的还挺像样的。

说说怎么实现的吧。打磨一个聊天气泡的想法由来已久。

WinForm

最开始用的WInForm,想重绘ListBox或者RichTextBox来做,可是借助万能的度娘也没找到思路,不熟悉GDI+,更不知道怎么去重绘。

Layui

后来看到Layui中的IM组件挺符合我的需求,想到可以借助CefSharp实现客户端和前端的联动,最终由于不熟悉前端,不知道怎么屏蔽边框和拖动,想法又泡汤了。

WPF下聊天气泡的实现_第2张图片

WPF

直到某天入了WPF的坑,由于它自带界面和逻辑分离的天然优势,完全可以重写LabelDataTemplate来实现,特别简单。

三、实现

思路很简单,重写ListView的模板,针对接收/发送两种行为分别定义两个模板,再定义一个模板选择器DataTemplateSelector判断要应用哪个模板。

定义ChatBubble

考虑到气泡中不仅仅显示文本,还可能会有图片和表情符号,我们可以重写Label的模板,分头像和内容两部分,内容的边框作成气泡的样子。

直接上代码,这是接收的气泡。


同样的,再定义一个发送的气泡。


定义TemplateSelector

接下来轮到TemplateSelector出场,最终气泡要通过ListView呈现,可以在ItemSource中指定一个标记位IsSend来告知UI是接收还是发送

class ChatBubbleSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var u = container as FrameworkElement;

        MessageEntity message = item as MessageEntity;

        if (message.IsSend)
            return u.FindResource("chatSend") as DataTemplate;
        else
            return u.FindResource("chatRecv") as DataTemplate;
    }
}

声明资源

然后在主界窗口中声明这个选择器,以及背景颜色等资源,配色取自微信PC端。

#F5F5F5



#F7F7F7



#98E165



#F6F6F6



#07C160


主界面实现

最后在主界面上放一个ListView,用来承载消息。


    
        
    

在ViewModel中绑定数据源,F5运行,就能看到文章一开始的效果了。

最后的最后,附上本文用到的Demo:https://gitee.com/dswfort/BlogDemos/tree/master/ChartBubbleSample

2020年5月2日星期六

你可能感兴趣的:(WPF项目经验,wpf)