为了账号安全,请及时绑定邮箱和手机立即绑定

WPF 语言格式化文本控件

标签:
Java

前言

本章讲述正确添加语言资源的方式,以及一段语言资源的多种样式显示。

例如:“@Winter,你好!感谢已使用软件 800 天!”

 

在添加如上多语言资源项时,“XX,你好!感谢已使用软件 X 天!”

那么,你是怎么添加语言资源的呢?

分别添加,“,你好!”、“感谢已使用软件”、“年”3个,再通过界面绑定动态变量 昵称和使用天数

假如你是按照如上添加语言资源的,那么问题来了,添加如上英文语言资源呢?是不是也分别添加单个资源,再拼凑绑定?

添加语言资源

正确的做法是,添加整个语言资源,“{0},你好!感谢已使用软件 {1} 天!”

原因:使用格式化的语言资源,那么将中文资源翻译成英文或者其它语言后,得到的译文才符合原有的含义。

不然,一段一段翻译后的文本拼接,得到的只会是,中式英文之类的。。。

语言格式化控件

在添加了语言资源后,如何在WPF界面显示呢?

简单的文本样式

假如只是实现简单的文本拼接,且样式相同时,可以直接绑定动态变量值 - 昵称和使用年限,然后通过StringFormat或者Conveter去处理格式化文本。

  • 如果只有一个动态变量,直接使用StringFormat处理即可。Text="{Binding Name,StringFormat={StaticResource TheFormatedText}}"

  • 如果多个动态变量,可以使用多重绑定+Converter,实现文本格式化。

复杂的文本样式

假如格式化文本,需要实现复杂的样式和操作,例如:

  1. 文本+按钮

  2. 文本+超链接

  3. 加粗文本+普通文本+红色文本

以上,如何处理?

语言格式化控件实现

Demo显示效果:

 1. 添加一个继承TextBlock的用户控件ComplexTextBlock

复制代码

1     /// <summary>2     /// 解决复杂文本格式化样式的文本框控件3     /// 如"已使用软件 {0} 天",天数需要标红加粗,或者用于【文本】【文字按钮】【文本】的组合4     /// </summary>5     public class ComplexTextBlock : TextBlock6     {7 8     }

复制代码

2. 重写文本依赖属性

为了监听文本变更,所以重写文本的依赖属性。文本变更事件处理,之后会详细介绍~

复制代码

 1     public new static DependencyProperty TextProperty = 2         DependencyProperty.Register("Text", typeof(string), typeof(ComplexTextBlock), new PropertyMetadata(TextPropertyChanged)); 3  4     public static string GetText(DependencyObject element) 5     { 6         return (string)element.GetValue(TextProperty); 7     } 8     public static void SetText(DependencyObject element, string value) 9     {10         element.SetValue(TextProperty, value);11     }12 13     private static void TextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)14     {15         LoadComplexContent(d);16     }

复制代码

3. 添加动态变量显示的控件列表

如“@Winter,你好!感谢已使用软件 800 天,可查看详情!”,可以将昵称、使用时间、详情,分别设置为文本控件、文本控件、超链接按钮,然后添加到动态控件列表中。

 

复制代码

 1     public static DependencyProperty ContentFormatsProperty = 2         DependencyProperty.Register("ContentFormats", typeof(ContentFormatsCollection), typeof(ComplexTextBlock), 3             new PropertyMetadata(default(ContentFormatsCollection), ContentFormatsPropertyChanged)); 4  5     /// <summary> 6     /// 格式化内容列表 7     /// </summary> 8     public ContentFormatsCollection ContentFormats 9     {10         get => (ContentFormatsCollection)GetValue(ContentFormatsProperty);11         set => SetValue(ContentFormatsProperty, value);12     }13 14     private static void ContentFormatsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)15     {16         LoadComplexContent(d);17     }

复制代码

 

4. 处理格式化文本

处理方法,主要是将当前格式化的文本拆分为多个文本段落和格式化字符“{0}”,然后将待显示的动态变量(文本控件/按钮等)替换拆分后列表中的格式化字符。组合成完整的显示文本。

其中,需要注意的是,文本的样式继承。

复制代码

  1     private const string FormattedKey = "{0}";  2   3     /// <summary>  4     /// 加载复杂文本  5     /// </summary>  6     /// <param name="dependencyObject"></param>  7     private static void LoadComplexContent(DependencyObject dependencyObject)  8     {  9         if (!(dependencyObject is ComplexTextBlock complexTextBlock)) 10         { 11             return; 12         } 13  14         string text = GetText(complexTextBlock); 15         var contentFormats = complexTextBlock.ContentFormats; 16  17         if (string.IsNullOrEmpty(text) || contentFormats == null || contentFormats.Count == 0) 18         { 19             return; 20         } 21  22         for (int i = 0; i < contentFormats.Count; i++) 23         { 24             text = text.Replace(i.ToString(), "0"); 25         } 26  27         var list = GetTextList(text); 28  29         //清空当前文本 30         complexTextBlock.Text = null; 31         //分段加载文本 32         var stackPanel = new StackPanel(); 33         stackPanel.Orientation = Orientation.Horizontal; 34         stackPanel.VerticalAlignment = VerticalAlignment.Center; 35  36         int formatIndex = 0; 37         foreach (var paraText in list) 38         { 39             if (paraText == FormattedKey) 40             { 41                 stackPanel.Children.Add(contentFormats[formatIndex++]); 42             } 43             else 44             { 45                 var textLine = new TextBlock(); 46                 if (complexTextBlock.Style != null) 47                 { 48                     textLine.Style = complexTextBlock.Style; 49                 } 50                 else 51                 { 52                     textLine.VerticalAlignment = complexTextBlock.VerticalAlignment; 53                     textLine.HorizontalAlignment = complexTextBlock.HorizontalAlignment; 54                     textLine.Background = complexTextBlock.Background; 55                     textLine.FontFamily = complexTextBlock.FontFamily; 56                     textLine.FontSize = complexTextBlock.FontSize; 57                     textLine.Foreground = complexTextBlock.Foreground; 58                     textLine.FontWeight = complexTextBlock.FontWeight; 59                     textLine.FontStyle = complexTextBlock.FontStyle; 60                 } 61                 textLine.Text = paraText; 62                 stackPanel.Children.Add(textLine); 63             } 64         } 65         complexTextBlock.Inlines.Add(stackPanel); 66     } 67  68     /// <summary> 69     /// 获取分段文本列表 70     /// </summary> 71     /// <param name="text"></param> 72     /// <returns></returns> 73     private static List<string> GetTextList(string text) 74     { 75         var list = new List<string>(); 76         var formatIndex = text.IndexOf(FormattedKey, StringComparison.Ordinal); 77  78         //1.不存在格式化关键字,则直接返回当前文本 79         if (formatIndex == -1) 80         { 81             list.Add(text); 82             return list; 83         } 84  85         //2.存在格式化关键字 86         if (formatIndex == 0) 87         { 88             list.Add(FormattedKey); 89         } 90         else 91         { 92             list.Add(text.Substring(0, formatIndex)); 93             list.Add(FormattedKey); 94         } 95  96         //获取下一格式化文本 97         if (formatIndex < text.Length) 98         { 99             list.AddRange(GetTextList(text.Substring(formatIndex + FormattedKey.Length)));100         }101 102         return list;103     }

复制代码

5. 控件的使用

界面显示:

调用实现:

复制代码

1     <local:ComplexTextBlock Text="小王,好好{0},详见{1}!" Style="{StaticResource ComplexTextBlockStyle}" Margin="0 10 0 0">2         <local:ComplexTextBlock.ContentFormats>3             <local:ContentFormatsCollection>4                 <Button Content="学习" Click="ButtonBase_OnClick" VerticalAlignment="Center"></Button>5                 <Button x:Name="LinkedButton" Content="学习计划" Click="LinkedButton_OnClick" Style="{StaticResource LinkedTextBlock}" VerticalAlignment="Center"/>6             </local:ContentFormatsCollection>7         </local:ComplexTextBlock.ContentFormats>8     </local:ComplexTextBlock>

复制代码

详细代码实现,可查看Github源码Demo

原文出处:https://www.cnblogs.com/kybs0/p/9688933.html  

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消