63 lines
2.8 KiB
C#
63 lines
2.8 KiB
C#
using System.Globalization;
|
||
using System.Text.RegularExpressions;
|
||
using System.Windows.Data;
|
||
using System.Windows.Documents;
|
||
|
||
namespace NeoUI.Converters;
|
||
|
||
/// <summary>
|
||
/// StringToMarkDownConverter 类用于将普通字符串转换为具有Markdown格式的富文本显示。该类实现了IValueConverter接口,主要功能是通过正则表达式识别并处理字符串中的代码块(以反引号`包围的部分),将其转换为带有特定前景色和背景色的富文本Run对象,并嵌入到TextBlock中返回。
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// 本转换器特别适用于需要在WPF应用程序中展示含有内联代码样式的Markdown文本的情况。它会自动处理输入字符串中的换行符,并将匹配到的代码片段高亮显示。
|
||
/// </remarks>
|
||
public class StringToMarkDownConverter : IValueConverter
|
||
{
|
||
// Explicit static constructor to tell C# compiler
|
||
// not to mark type as beforefieldinit
|
||
private StringToMarkDownConverter() { }
|
||
|
||
/// <summary>
|
||
/// 获取 StringToMarkDownConverter 的单例实例。此属性确保在整个应用程序生命周期中只有一个 StringToMarkDownConverter 实例被创建和使用,从而提高性能并减少内存占用。
|
||
/// </summary>
|
||
/// <returns>返回一个 StringToMarkDownConverter 类型的实例。</returns>
|
||
/// <remarks>
|
||
/// 该属性通过延迟初始化(Lazy Initialization)模式来实现单例模式,首次访问时才创建实例。这样可以保证在多线程环境下也能安全地获取到唯一的实例。
|
||
/// </remarks>
|
||
public readonly static StringToMarkDownConverter Instance = new StringToMarkDownConverter();
|
||
|
||
/// <inheritdoc />
|
||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||
{
|
||
var str = value as string;
|
||
var textBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap };
|
||
|
||
if (string.IsNullOrEmpty(str)) return textBlock;
|
||
const string pattern = @"`(.*?)`";
|
||
var index = 0;
|
||
|
||
var inlines = textBlock.Inlines;
|
||
str = str?.Replace(@"\n", Environment.NewLine);
|
||
|
||
var foreground = new SolidColorBrush(Color.FromRgb(31, 46, 59));
|
||
var background = new SolidColorBrush(Color.FromRgb(242, 244, 245));
|
||
|
||
if (str == null) return textBlock;
|
||
foreach (Match match in Regex.Matches(str, pattern))
|
||
{
|
||
inlines.Add(str.Substring(index, match.Index - index));
|
||
inlines.Add(new Run(match.Value.Replace('`', ' ')) { Foreground = foreground, Background = background });
|
||
index = match.Index + match.Length;
|
||
}
|
||
|
||
inlines.Add(str.Substring(index));
|
||
|
||
return textBlock;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||
{
|
||
return DependencyProperty.UnsetValue;
|
||
}
|
||
} |