零、版本履历

日期 说明
2020.05.02 初稿

一、效果

先看最终效果。

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

二、由来

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

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

WinForm

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

Layui

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

WPF

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

三、实现

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

定义ChatBubble

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

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

<Style TargetType="Label" x:Key="chatRecv"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Label}"><Grid Margin="0,5,0,5"><Grid.ColumnDefinitions><ColumnDefinition Width="40" /><ColumnDefinition Width="*" /></Grid.ColumnDefinitions><Image Width="35" Height="35" Source="userIcon.jpg" /><Border x:Name="border1" Grid.Column="1" CornerRadius="1" BorderBrush="#EDEDED" BorderThickness="1" VerticalAlignment="Top" Margin="10,2,0,2" Background="#FFFFFF" HorizontalAlignment="Left" Padding="5" MinHeight="35"MinWidth="50"><ContentPresenter VerticalAlignment="Center" /></Border><Canvas Grid.Column="1" Width="10" Height="16" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="3,14,0,0" Background="Transparent"><Path x:Name="path1" Stroke="#EDEDED" StrokeThickness="1" Fill="#FFFFFF"><Path.Data><PathGeometry Figures="M 8,0 L 0,6,8,12"/></Path.Data></Path></Canvas></Grid><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="path1" Property="Fill" Value="#F6F6F6" /><Setter TargetName="border1" Property="Background" Value="#F6F6F6" /></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style>

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

<Style TargetType="Label" x:Key="chatSend"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Label}"><Grid Margin="0,5,0,5"><Grid.ColumnDefinitions><ColumnDefinition Width="*" /><ColumnDefinition Width="40" /></Grid.ColumnDefinitions><Image Grid.Column="1" Width="35" Height="35" Source="userIcon.jpg" /><Border x:Name="border1" CornerRadius="1"BorderBrush="#9EEA6A"BorderThickness="1" VerticalAlignment="Top"HorizontalAlignment="Right"Margin="0,2,10,2" Background="#9EEA6A" Padding="5" MinHeight="35" MinWidth="50"><ContentPresenter VerticalAlignment="Center" /></Border><Canvas Width="10" Height="16" HorizontalAlignment="Right" VerticalAlignment="Top"Margin="5,14,0,0" Background="Transparent"><Path x:Name="path1" Stroke="#9EEA6A" StrokeThickness="0.5"Fill="#9EEA6A"><Path.Data><PathGeometry Figures="M 0,12 L 0,0,8,6"/></Path.Data></Path></Canvas></Grid><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="path1" Property="Fill" Value="#98E165" /><Setter TargetName="border1"Property="Background" Value="#98E165" /></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style>

定义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;elsereturn u.FindResource("chatRecv") as DataTemplate;}
}

声明资源

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

<Color x:Key="background">#F5F5F5</Color><SolidColorBrush x:Key="background_brush" Color="{StaticResource background}" options:Freeze="True" /><Color x:Key="icon_btn_normal">#F7F7F7</Color><SolidColorBrush x:Key="icon_btn_normal_brush" Color="{StaticResource icon_btn_normal}" options:Freeze="True" /><Color x:Key="message_send_bg">#98E165</Color><SolidColorBrush x:Key="message_send_bg_brush" Color="{StaticResource message_send_bg}" options:Freeze="True" /><Color x:Key="message_recv_bg">#F6F6F6</Color><SolidColorBrush x:Key="message_recv_bg_brush" Color="{StaticResource message_recv_bg}" options:Freeze="True" /><Color x:Key="green_normal">#07C160</Color><SolidColorBrush x:Key="green_normal_brush" Color="{StaticResource green_normal}" options:Freeze="True" />

主界面实现

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

<ListBox ItemTemplateSelector="{StaticResource chatBubbleSelector}" ItemsSource="{Binding Messages}" Background="{DynamicResource background_brush}" SelectedIndex="{Binding SelectedMessage}" BorderThickness="0,1,0,1" BorderBrush="#D3D3D3"ScrollViewer.HorizontalScrollBarVisibility="Disabled"><ListBox.ItemContainerStyle><Style TargetType="{x:Type ListBoxItem}" x:Key="listViewItemStyle"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type ListBoxItem}"><Border Name="Bd"Background="{TemplateBinding Background}"BorderBrush="{TemplateBinding BorderBrush}"BorderThickness="{TemplateBinding BorderThickness}"Padding="{TemplateBinding Padding}"SnapsToDevicePixels="true"><ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/></Border></ControlTemplate></Setter.Value></Setter><Setter Property="HorizontalContentAlignment" Value="Stretch"/><Setter Property="FocusVisualStyle" Value="{x:Null}" /></Style></ListBox.ItemContainerStyle>
</ListBox>

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

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

2020年5月2日星期六

WPF下聊天气泡的实现相关推荐

  1. WPF 仿微信聊天气泡

    先上图 GitHub 参考文章: WPF下聊天气泡的实现

  2. java 气泡聊天消息_CSS3 巧妙实现聊天气泡

    前一阵子敢玩的 Mobile 页改版完成了,就之前的页面风格更加扁平化,从暗色系为主背景转到亮色背景,去掉更多的阴影,给用户简约的体验风格,哈哈我不是设计师不过多评价啦.感兴趣的朋友可以直接去 ida ...

  3. HTML怎么做类似QQ聊天气泡,h5实现QQ聊天气泡的实例介绍

    这篇文章主要介绍了HTML5实现QQ聊天气泡效果,用 HTML/CSS 做了个类似QQ的聊天气泡,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 今天自己用 HTML/CSS 做了个类似QQ的聊天气 ...

  4. 微信气泡主题设置_微信猫和老鼠主题怎么弄?猫和老鼠聊天气泡主题设置教程...

    阅读本文前,请您先点击上面的"科技阿",再点击"关注",这样您就可以继续免费收到文章了.每天都会有分享,都是免费订阅,请您放心关注.  注:本文转载自网络,如有 ...

  5. 聊天气泡图片的动态拉伸、适配与镜像

    聊天气泡图片的动态拉伸.适配与镜像 前情提要 创建.9.png格式的图片 从资源文件夹加载.9.png图片 从本地文件加载".9.png"图片 项目痛点 进阶探索 iOS中的方式 ...

  6. UI设计中聊天气泡框的设计技巧

    聊天气泡我们很熟悉,每天都要和他打交道.早上醒来第一-件事你是不是打开微信看看.那在和朋友聊天时,你有没有这样的疑问,为什么输入文字多少不同,气泡的展示也不同?为什么发送不同比例的图片,其缩略图的展示 ...

  7. android气泡组件,Android 聊天气泡

    网上搜到的只有一篇是自定义的TextView,其使用比较麻烦,所以采用大众化的方法--使用9.png来实现. 这里主要介绍sdk tool的draw9patch.bat的使用. 这个bat执行文件打开 ...

  8. 在Android Studio如何制作聊天气泡

    在Android Studio如何制作一个聊天气泡 最近在学习移动编程开发,利用Android Studio编写代码.作为初学者,多多少少会有点难.        在开发的过程中,遇到了很多的困难,而 ...

  9. Android点9图机制及在聊天气泡中的应用

    点九图简介 Android为了使用同一张图作为不同数量文字的背景,设计了一种可以指定区域拉伸的图片格式".9.png",这种图片格式就是点九图. 注意:这种图片格式只能被使用于An ...

最新文章

  1. Nignx集成fastDFS后访问Nginx一直在加载中解决
  2. 【java实训课】web网页相关知识点总结
  3. 单行子查询返回多个行_sql多表查询练习,习题总结
  4. 一句话概括4本管理著作
  5. 决策树 随机森林 xgboost_一文看懂随机森林-RandomForest(附4个构造步骤+4种实现方式评测+10个优缺点)...
  6. L1-006. 连续因子-PAT团体程序设计天梯赛
  7. python实现整数反转
  8. linux cpu使用率 理解,深入理解Linux的CPU使用率
  9. 区块链≠分布式账本,别再傻傻分不清
  10. 自习室预约小程序有哪些功能?
  11. 计算机无法访问苹果相册,iPhone与电脑连接后找不到照片怎么办?掌握这三个技巧,烦恼问题轻松解决!...
  12. VMware ESXI 5.5 死机 红屏问题
  13. DS18B20温度采集报警系统,原理及汇编、C语言实现
  14. linux IRQ Management(六)- DTS及调试
  15. 开关电源补偿环路设计(1):基础部分-以Buck 为例
  16. 反射镜镀膜与波长关系
  17. 用Python助女神发朋友圈
  18. 怎么把aac转mp3格式?这几种转换方式建议学习一下
  19. PEG包裹碳化硅(SiC)量子点荧光材料
  20. 用Python端对端数据分析识别机器人“僵尸粉”

热门文章

  1. 解决数据迁移过程中主键冲突的问题
  2. 苹果开发者账号(个人、公司、企业)的区别
  3. 机器学习-特征抽取(主成分分析法/因子分析法/非负矩阵因子分解NMF算法)
  4. 在centos7中下载搜狗输入法
  5. 梅科尔工作室——HarmonyOS应用开发培训第三次作业
  6. C++ 与、或、异或、取反等运算
  7. 计算机毕业设计之微信小程序的商城 购物系统 app论文
  8. Unicode 码和汉字,十进制之间互转!二进制、十六进制,十进制的转换
  9. python 0x0101_Python中ASCII转十六进制、C中BCD转十进制、十六进制学习记录
  10. Android看韩漫软件,第一韩漫app-第一韩漫安卓版v1.0