珠海制作公司网站,编程加盟一般多少钱,便宜的云服务器租用,网页设计工具有哪些祝大家端午节安康#xff01;WPF开发者QQ群#xff1a; 340500857 前言 有小伙伴需要实现类似微信一样的气泡聊天emoji表情文本。欢迎转发、分享、点赞#xff0c;谢谢大家~。 效果预览#xff08;更多效果请下载源码体验#xff09;#xff1a;一、EmojiAndTextControl… 祝大家端午节安康WPF开发者QQ群 340500857 前言 有小伙伴需要实现类似微信一样的气泡聊天emoji表情文本。欢迎转发、分享、点赞谢谢大家~。 效果预览更多效果请下载源码体验一、EmojiAndTextControl.cs代码如下/**Github https://github.com/yanjinhuagood/WPFDevelopers.git码云 https://gitee.com/yanjinhua/WPFDevelopers.git**/
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;namespace WpfChatEmojiText
{[TemplatePart(Name TextBlockTemplateName, Type typeof(TextBlock))][TemplatePart(Name WrapPanelLeftTemplateName, Type typeof(WrapPanel))][TemplatePart(Name BorderTemplateName, Type typeof(Border))][TemplatePart(Name WrapPanelRightTemplateName, Type typeof(WrapPanel))][TemplatePart(Name ImageBrushLeftTemplateName, Type typeof(ImageBrush))][TemplatePart(Name ImageBrushRightTemplateName, Type typeof(ImageBrush))]public class EmojiAndTextControl: Control{private static readonly Type _typeofSelf typeof(EmojiAndTextControl);private const string TextBlockTemplateName PART_TextBlock;private const string WrapPanelLeftTemplateName PART_Left;private const string BorderTemplateName PART_Border;private const string WrapPanelRightTemplateName PART_Right;private const string ImageBrushLeftTemplateName LeftUser;private const string ImageBrushRightTemplateName RightUser;private TextBlock m_textBlock;private WrapPanel leftWrapPanel;private Border border;private WrapPanel rightWrapPanel;private ImageBrush leftImageBrush;private ImageBrush rightImageBrush;private bool m_IgnoreChanges false;public string Text{get { return (string)GetValue(TextProperty); }set { SetValue(TextProperty, value); }}static EmojiAndTextControl(){DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf, new FrameworkPropertyMetadata(_typeofSelf));}public override void OnApplyTemplate(){base.OnApplyTemplate();m_textBlock GetTemplateChild(TextBlockTemplateName) as TextBlock;leftWrapPanel GetTemplateChild(WrapPanelLeftTemplateName) as WrapPanel;border GetTemplateChild(BorderTemplateName) as Border;rightWrapPanel GetTemplateChild(WrapPanelRightTemplateName) as WrapPanel;leftImageBrush GetTemplateChild(ImageBrushLeftTemplateName) as ImageBrush;rightImageBrush GetTemplateChild(ImageBrushRightTemplateName) as ImageBrush;UpdateEmoji();UpdateIsRight();UpdateRightImageSource();UpdateLeftImageSource();}public static readonly DependencyProperty TextProperty DependencyProperty.Register(Text, typeof(string), typeof(EmojiAndTextControl),new UIPropertyMetadata(string.Empty, OnTextChanged));static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){EmojiAndTextControl emoji (EmojiAndTextControl)d;emoji.UpdateEmoji();}void UpdateEmoji(){if (m_textBlock null) return;if (!m_IgnoreChanges){m_IgnoreChanges true;//EmojiHelper.ParseText(m_textBlock);EmojiHelperLibrary.EmojiHelper.Instance.ParseText(m_textBlock);m_IgnoreChanges false;}}public bool IsRight{get { return (bool)GetValue(IsRightProperty); }set { SetValue(IsRightProperty, value); }}public static readonly DependencyProperty IsRightProperty DependencyProperty.Register(IsRight, typeof(bool), typeof(EmojiAndTextControl), new UIPropertyMetadata(OnIsRightChanged));static void OnIsRightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){EmojiAndTextControl control (EmojiAndTextControl)d;control.UpdateIsRight();}void UpdateIsRight(){if (leftWrapPanel null||border null||rightWrapPanel null) return;if (!IsRight){leftWrapPanel.Visibility Visibility.Visible;border.Background Brushes.White;rightWrapPanel.Visibility Visibility.Collapsed;}}public ImageSource LeftImageSource{get { return (ImageSource)GetValue(LeftImageSourceProperty); }set { SetValue(LeftImageSourceProperty, value); }}public static readonly DependencyProperty LeftImageSourceProperty DependencyProperty.Register(LeftImageSource, typeof(ImageSource), typeof(EmojiAndTextControl), new UIPropertyMetadata(OnLeftImageSourceChanged));private static void OnLeftImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){EmojiAndTextControl control (EmojiAndTextControl)d;control.UpdateLeftImageSource();}void UpdateLeftImageSource(){if (leftImageBrush null) return;leftImageBrush.ImageSource LeftImageSource;}public ImageSource RightImageSource{get { return (ImageSource)GetValue(RightImageSourceProperty); }set { SetValue(RightImageSourceProperty, value); }}public static readonly DependencyProperty RightImageSourceProperty DependencyProperty.Register(RightImageSource, typeof(ImageSource), typeof(EmojiAndTextControl), new UIPropertyMetadata(OnRightImageSourceChanged));private static void OnRightImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){EmojiAndTextControl control (EmojiAndTextControl)d;control.UpdateRightImageSource();}void UpdateRightImageSource(){if (rightImageBrush null) return;rightImageBrush.ImageSource RightImageSource;}}
}二、EmojiAndTextControlStyle.xaml代码如下ResourceDictionary xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:localclr-namespace:WpfChatEmojiTextStyle TargetTypelocal:EmojiAndTextControlSetter PropertyTemplateSetter.ValueControlTemplate TargetTypelocal:EmojiAndTextControlGridGrid.ColumnDefinitionsColumnDefinition WidthAuto/ColumnDefinition/ColumnDefinition WidthAuto//Grid.ColumnDefinitionsWrapPanel Grid.Column0 NamePART_Left VisibilityCollapsedBorder Width35 Height35 VerticalAlignmentTopMargin0,10CornerRadius4UseLayoutRoundingTrueBorder.BackgroundImageBrush x:NameLeftUserImageSource{TemplateBinding LeftImageSource} RenderOptions.BitmapScalingModeLowQuality StretchFill//Border.Background/BorderPath DataM365.714 256v512q0 14.857-10.857 25.714t-25.714 10.857-25.714-10.857l-256-256q-10.857-10.857-10.857-25.714t10.857-25.714l256-256q10.857-10.857 25.714-10.857t25.714 10.857 10.857 25.714zFillWhite Width10 Height10 StretchFillStrokeThickness0 Grid.Column1VerticalAlignmentTop Margin0,20,-14,0UseLayoutRoundingTrue SnapsToDevicePixelsTrue//WrapPanelBorder CornerRadius4 Background#9EEA6AUseLayoutRoundingTrue SnapsToDevicePixelsTrueGrid.Column1 Margin10NamePART_BorderTextBlock NamePART_TextBlock FontSize15 Text{TemplateBinding Text}Padding6 TextWrappingWrap VerticalAlignmentCenter//BorderWrapPanel Grid.Column2 NamePART_RightPath DataM329.143 512q0 14.857-10.857 25.714l-256 256q-10.857 10.857-25.714 10.857t-25.714-10.857-10.857-25.714v-512q0-14.857 10.857-25.714t25.714-10.857 25.714 10.857l256 256q10.857 10.857 10.857 25.714zFill#9EEA6A Width10 Height10 StretchFillStrokeThickness0 VerticalAlignmentTop Margin-14,20,0,0UseLayoutRoundingTrue SnapsToDevicePixelsTrue/Border Width35 Height35VerticalAlignmentTopMargin0,10CornerRadius4UseLayoutRoundingTrueBorder.BackgroundImageBrush x:NameRightUserImageSource{TemplateBinding RightImageSource} RenderOptions.BitmapScalingModeLowQuality StretchFill//Border.Background/Border/WrapPanel/Grid!--ControlTemplate.TriggersDataTrigger Binding{Binding IsRight} ValuefalseSetter PropertyVisibility TargetNamePART_Left ValueVisible/Setter PropertyBackground TargetNamePART_Border ValueWhite/Setter PropertyVisibility TargetNamePART_Right ValueCollapsed//DataTrigger/ControlTemplate.Triggers--/ControlTemplate/Setter.Value/Setter
/Style
/ResourceDictionary
三、MainWindow.xaml代码如下Window x:ClassWpfChatEmojiText.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:WpfChatEmojiTextmc:IgnorabledTitleWPFDevelopers Height800 Width800TextOptions.TextFormattingModeDisplay UseLayoutRoundingTrueSnapsToDevicePixelsTrue RenderOptions.BitmapScalingModeNearestNeighborUniformGrid Columns2Grid Margin10,0Grid.RowDefinitionsRowDefinition/RowDefinition Height100//Grid.RowDefinitionsRichTextBox x:Name_LeftChat IsReadOnlyTrueRichTextBox.BackgroundImageBrush ImageSourceImages\Left.jpg StretchFill//RichTextBox.Background/RichTextBoxGrid Grid.Row1Grid.RowDefinitionsRowDefinition HeightAuto/RowDefinition//Grid.RowDefinitionsToggleButton x:NameLeftButtonEmoji Margin10,0 ContentEmoji Width40 HorizontalAlignmentLeft/Popup PlacementTop PlacementTarget{Binding ElementNameLeftButtonEmoji} IsOpen{Binding ElementNameLeftButtonEmoji,PathIsChecked} AllowsTransparencyTrue VerticalOffset-4Border Margin10 BackgroundWhite CornerRadius4Width76Border.EffectDropShadowEffect ShadowDepth0 BlurRadius10 Opacity0.2 Color#80000000//Border.EffectItemsControl ItemsSource{Binding EmojiArray,RelativeSource{RelativeSource AncestorTypelocal:MainWindow}}ItemsControl.ItemTemplateDataTemplateBorder x:NamePART_Border CornerRadius2PreviewMouseLeftButtonDownPART_Border_PreviewMouseLeftButtonDownTag{Binding Key}Image Source{Binding Value} ToolTip{Binding Name}Width30 Height30 Margin4IsHitTestVisibleTrue//BorderDataTemplate.TriggersTrigger PropertyIsMouseOver ValueTrueSetter PropertyBackground TargetNamePART_Border Value#FFD8D1D1//Trigger/DataTemplate.Triggers/DataTemplate/ItemsControl.ItemTemplateItemsControl.ItemsPanelItemsPanelTemplateWrapPanel//ItemsPanelTemplate/ItemsControl.ItemsPanel/ItemsControl/Border/PopupGrid Grid.Row1Grid.ColumnDefinitionsColumnDefinition/ColumnDefinition WidthAuto//Grid.ColumnDefinitionsTextBox x:NameLeftInput/Button Grid.Column1 Content发送 x:NameLeftSend ClickLeftSend_Click/Button/Grid/Grid/GridGrid Margin10,0Grid.RowDefinitionsRowDefinition/RowDefinition Height100//Grid.RowDefinitionsRichTextBox x:Name_RightChat IsReadOnlyTrueRichTextBox.BackgroundImageBrush ImageSourceImages\Right.jpg StretchFill//RichTextBox.Background/RichTextBoxGrid Grid.Row1Grid.RowDefinitionsRowDefinition HeightAuto/RowDefinition//Grid.RowDefinitionsToggleButton x:NameRightButtonEmoji Margin10,0 ContentEmoji Width40 HorizontalAlignmentLeft/Popup PlacementTop PlacementTarget{Binding ElementNameRightButtonEmoji} IsOpen{Binding ElementNameRightButtonEmoji,PathIsChecked} AllowsTransparencyTrue VerticalOffset-4Border Margin10 BackgroundWhite CornerRadius4Width76Border.EffectDropShadowEffect ShadowDepth0 BlurRadius10 Opacity0.2 Color#80000000//Border.EffectItemsControl ItemsSource{Binding EmojiArray,RelativeSource{RelativeSource AncestorTypelocal:MainWindow}}ItemsControl.ItemTemplateDataTemplateBorder x:NamePART_Border CornerRadius2PreviewMouseLeftButtonDownPART_Border_RightPreviewMouseLeftButtonDownTag{Binding Key}Image Source{Binding Value} ToolTip{Binding Name}Width30 Height30 Margin4IsHitTestVisibleTrue//BorderDataTemplate.TriggersTrigger PropertyIsMouseOver ValueTrueSetter PropertyBackground TargetNamePART_Border Value#FFD8D1D1//Trigger/DataTemplate.Triggers/DataTemplate/ItemsControl.ItemTemplateItemsControl.ItemsPanelItemsPanelTemplateWrapPanel//ItemsPanelTemplate/ItemsControl.ItemsPanel/ItemsControl/Border/PopupGrid Grid.Row1Grid.ColumnDefinitionsColumnDefinition/ColumnDefinition WidthAuto//Grid.ColumnDefinitionsTextBox x:NameRightInput/Button Grid.Column1 Content发送 x:NameRightSend ClickRightSend_Click/Button/Grid/Grid/Grid/UniformGrid
/Window
四、MainWindow.cs.xaml代码如下using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;namespace WpfChatEmojiText
{/// summary/// MainWindow.xaml 的交互逻辑/// /summarypublic partial class MainWindow : Window{public IEnumerable EmojiArray{get { return (IEnumerable)GetValue(EmojiArrayProperty); }set { SetValue(EmojiArrayProperty, value); }}public static readonly DependencyProperty EmojiArrayProperty DependencyProperty.Register(EmojiArray, typeof(IEnumerable), typeof(MainWindow), new PropertyMetadata(null));public MainWindow(){InitializeComponent();var emojiModels new ListEmojiModel();EmojiHelperLibrary.EmojiHelper.Instance._emojiHeight 30;EmojiHelperLibrary.EmojiHelper.Instance._emojiWidth 30;var m_Emojis new Dictionarystring, string();var emojiPath Path.Combine(AppDomain.CurrentDomain.BaseDirectory, emoji);var directory new DirectoryInfo(emojiPath);foreach (var item in directory.GetFiles()){var _key $[{Path.GetFileNameWithoutExtension(item.Name)}];m_Emojis.Add(_key, item.FullName);emojiModels.Add(new EmojiModel { Name Path.GetFileNameWithoutExtension(item.Name), Key _key, Value item.FullName });}EmojiHelperLibrary.EmojiHelper.Instance.m_Emojis m_Emojis;EmojiArray emojiModels;}private void PART_Border_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e){LeftButtonEmoji.IsChecked false;var send sender as Border;LeftInput.Text send.Tag.ToString();LeftInput.Focus();LeftInput.SelectionStart LeftInput.Text.Length;}private void LeftSend_Click(object sender, RoutedEventArgs e){LeftChat();}void LeftChat(){var leftText new EmojiAndTextControl();leftText.IsRight true;leftText.RightImageSource new BitmapImage(new Uri(pack://application:,,,/Images/UserImages/jingtao.png));leftText.Text LeftInput.Text;var leftPara new Paragraph();leftPara.TextAlignment TextAlignment.Right;leftPara.Inlines.Add(leftText);_LeftChat.Document.Blocks.Add(leftPara);var rightText new EmojiAndTextControl();rightText.IsRight false;rightText.LeftImageSource new BitmapImage(new Uri(pack://application:,,,/Images/UserImages/jingtao.png));rightText.Text LeftInput.Text;var rightPara new Paragraph();rightPara.TextAlignment TextAlignment.Left;rightPara.Inlines.Add(rightText);_RightChat.Document.Blocks.Add(rightPara);LeftInput.Text string.Empty;LeftInput.Focus();}void RightChat(){var leftText new EmojiAndTextControl();leftText.IsRight true;leftText.RightImageSource new BitmapImage(new Uri(pack://application:,,,/Images/UserImages/yanjinhua.png));leftText.Text RightInput.Text;var leftPara new Paragraph();leftPara.TextAlignment TextAlignment.Right;leftPara.Inlines.Add(leftText);_RightChat.Document.Blocks.Add(leftPara);var rightText new EmojiAndTextControl();rightText.IsRight false;rightText.LeftImageSource new BitmapImage(new Uri(pack://application:,,,/Images/UserImages/yanjinhua.png));rightText.Text RightInput.Text;var rightPara new Paragraph();rightPara.TextAlignment TextAlignment.Left;rightPara.Inlines.Add(rightText);_LeftChat.Document.Blocks.Add(rightPara);RightInput.Text string.Empty;RightInput.Focus();}private void RightSend_Click(object sender, RoutedEventArgs e){RightChat();}private void PART_Border_RightPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e){RightButtonEmoji.IsChecked false;var send sender as Border;RightInput.Text send.Tag.ToString();RightInput.Focus();RightInput.SelectionStart RightInput.Text.Length;}}public class EmojiModel{public string Name { get; set; }public string Key { get; set; }public string Value { get; set; }}
}
源码地址githubhttps://github.com/yanjinhuagood/WPFDevelopers.gitgiteehttps://gitee.com/yanjinhua/WPFDevelopers.gitWPF开发者QQ群 340500857 blogs https://www.cnblogs.com/yanjinhuaGithubhttps://github.com/yanjinhuagood出处https://www.cnblogs.com/yanjinhua版权本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。转载请著名作者 出处 https://github.com/yanjinhuagood