63 lines
2.4 KiB
C#
63 lines
2.4 KiB
C#
using System.Globalization;
|
|
using System.Windows.Data;
|
|
using System.Windows.Documents;
|
|
|
|
namespace VariaStudio.Converters;
|
|
|
|
/// <summary>
|
|
/// StringMatchConverter 是一个实现了 IMultiValueConverter 接口的转换器,用于在 WPF 应用程序中实现文本匹配和高亮显示功能。
|
|
/// 该转换器接收两个字符串参数:原始文本和需要高亮的关键字。它会检查原始文本中是否包含关键字,并将匹配到的关键字以加粗样式显示。
|
|
/// 如果没有找到匹配项,则直接返回原始文本。
|
|
/// </summary>
|
|
public class StringMatchConverter : IMultiValueConverter
|
|
{
|
|
/// <summary>
|
|
/// 获取 StringMatchConverter 的单例实例,用于在绑定中直接引用,无需重复创建转换器对象。
|
|
/// 该属性确保了整个应用程序中只有一个 StringMatchConverter 实例,有助于提高性能和减少内存消耗。
|
|
/// </summary>
|
|
public static StringMatchConverter Instance { get; } = new();
|
|
|
|
/// <inheritdoc />
|
|
public object? Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
|
{
|
|
if (values.Length < 2 || values[0] is not string text || values[1] is not string highlight)
|
|
{
|
|
return values.Length > 0 ? values[0] : null;
|
|
}
|
|
|
|
var textBlock = new TextBlock
|
|
{
|
|
TextTrimming = TextTrimming.CharacterEllipsis // 防止文本过长时溢出
|
|
};
|
|
|
|
if (string.IsNullOrEmpty(highlight) || string.IsNullOrEmpty(text))
|
|
{
|
|
textBlock.Text = text;
|
|
return textBlock;
|
|
}
|
|
|
|
// 使用 IndexOf 进行高效、不区分大小写的查找
|
|
var index = text.IndexOf(highlight, StringComparison.OrdinalIgnoreCase);
|
|
|
|
if (index == -1)
|
|
{
|
|
textBlock.Text = text;
|
|
return textBlock;
|
|
}
|
|
|
|
// 根据找到的索引来构建高亮文本
|
|
var matchedString = text.Substring(index, highlight.Length);
|
|
|
|
textBlock.Inlines.Add(new Run(text.Substring(0, index)));
|
|
textBlock.Inlines.Add(new Run(matchedString) { FontWeight = System.Windows.FontWeights.Bold });
|
|
textBlock.Inlines.Add(new Run(text.Substring(index + highlight.Length)));
|
|
|
|
return textBlock;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
} |