Wpf 如何使用附加属性为指定关键字突出显示文本块中的粗体字
目标是使用匹配的输入关键字加粗Textblock中文本的单词 例如:Stackoverflow是一个非常有用的工具,继续使用Stackoverflow来提高你的技能 当关键字为:Stackoverflow时,它现在应显示为 Stackoverflow是一个非常有用的工具,请继续使用Stackoverflow来提高您的技能 我试图使用附加属性来实现相同的目标。下面是相同的快照代码Wpf 如何使用附加属性为指定关键字突出显示文本块中的粗体字,wpf,xaml,Wpf,Xaml,目标是使用匹配的输入关键字加粗Textblock中文本的单词 例如:Stackoverflow是一个非常有用的工具,继续使用Stackoverflow来提高你的技能 当关键字为:Stackoverflow时,它现在应显示为 Stackoverflow是一个非常有用的工具,请继续使用Stackoverflow来提高您的技能 我试图使用附加属性来实现相同的目标。下面是相同的快照代码 public class HighLightKeyWord : DependencyObject { //T
public class HighLightKeyWord : DependencyObject
{
//This word is used to specify the word to highlight
public static readonly DependencyProperty BoldWordProperty = DependencyProperty.RegisterAttached("BoldWord", typeof(string), typeof(HighLightKeyWord),
new PropertyMetadata(string.Empty, OnBindingTextChanged));
public static string GetBoldWord(DependencyObject obj)
{
return (string)obj.GetValue(BoldWordProperty);
}
public static void SetBoldWord(DependencyObject obj, string value)
{
obj.SetValue(BoldWordProperty, value);
}
private static void OnBindingTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var _Key = e.NewValue as string;
var textblk = d as TextBlock;
string SourceText = textblk.Text;
SetBold(_Key, textblk, SourceText);
}
private static void SetBold(string key, TextBlock text, string SourceText)
{
text.Inlines.Clear();
var words = SourceText.Split(' ');
for (int i = 0; i < words.Length; i++)
{
var word = words[i];
var inline = new Run() { Text = word + ' ' };
if (String.Compare(word, key, StringComparison.CurrentCultureIgnoreCase) == 0)
{
inline.FontWeight = FontWeights.Bold;
}
text.Inlines.Add(inline);
}
}
}
在Xaml中,我将值绑定为
<TextBlock Text="{Binding Path=Text}" loc:HighLightKeyWord.BoldWord="{Binding Path=KeyWord}" />
上面的代码工作正常,但是当我通过数据绑定直接在xaml中设置HighlightText属性时,OnBindingTextChanged方法中文本块的Text属性变为空,并且在设置dependency属性时只调用一次该方法。
我使用这个基于拼写检查器概念的设计,以便其他团队成员可以在他们的项目中重用我的附加属性。
有人能建议如何解决这个问题吗?无论您想修改TextBlock FontWeight属性还是其他显示属性,我都编写了以下静态方法,并发现它非常有用。(注意:该方法通过修改前台属性来突出显示文本。相同的原理可用于任何其他TextBlock显示属性。) 您可以使用TextBlock扩展语法调用此方法,如下所示:
TextBlockTitle.SetTextAndHighlightSubstring(_categoryItem.ItemText, _searchText);
在本例中,出现以下显示:
我最近遇到了同样的问题,文本绑定被破坏了。我意识到这是一个老问题,但我想我还是会分享我的发现 基本上,文本属性的数据绑定在内联线一刻就被切断了。我解决这个问题的方法是添加一个内部文本依赖属性,该属性复制了文本的绑定,因此后续的文本更改将继续触发高亮显示 在清除text.Inlines之前,请尝试添加类似的内容
protected static string GetInternalText(DependencyObject obj)
{
return (string)obj.GetValue(InternalTextProperty)
}
protected static void SetInternalText(DependencyObject obj, string value)
{
obj.SetValue(InternalTextProperty, value);
}
// Using a DependencyProperty as the backing store for InternalText. This enables animation, styling, binding, etc...
protected static readonly DependencyProperty InternalTextProperty =
DependencyProperty.RegisterAttached("InternalText", typeof(string),
typeof(HighlightableTextBlock), new PropertyMetadata(string.Empty, OnInternalTextChanged));
private static void SetBold(string key, TextBlock text, string SourceText)
{
//Add the following code to replicate text binding
if (textblock.GetBindingExpression(HighlightableTextBlock.InternalTextProperty) == null)
{
var textBinding = text.GetBindingExpression(TextBlock.TextProperty);
if (textBinding != null)
{
text.SetBinding(HighLightKeyWord.InternalTextProperty, textBinding.ParentBindingBase);
}
}
...
}
在InternalTextProperty的propertyChangeCallback中,可以使用与OnBindingTextChanged()相同的代码,也可以将它们重构为另一个方法
对于那些不想自己编写代码的人。我创建了一个轻量级的nuget包,它向常规文本块添加高亮显示。您可以保留大部分代码不变,只需添加一些附加属性。默认情况下,该插件支持高亮显示,但您也可以在关键字上启用粗体、斜体和下划线
资料来源如下:
TextBlockTitle.SetTextAndHighlightSubstring(_categoryItem.ItemText, _searchText);
protected static string GetInternalText(DependencyObject obj)
{
return (string)obj.GetValue(InternalTextProperty)
}
protected static void SetInternalText(DependencyObject obj, string value)
{
obj.SetValue(InternalTextProperty, value);
}
// Using a DependencyProperty as the backing store for InternalText. This enables animation, styling, binding, etc...
protected static readonly DependencyProperty InternalTextProperty =
DependencyProperty.RegisterAttached("InternalText", typeof(string),
typeof(HighlightableTextBlock), new PropertyMetadata(string.Empty, OnInternalTextChanged));
private static void SetBold(string key, TextBlock text, string SourceText)
{
//Add the following code to replicate text binding
if (textblock.GetBindingExpression(HighlightableTextBlock.InternalTextProperty) == null)
{
var textBinding = text.GetBindingExpression(TextBlock.TextProperty);
if (textBinding != null)
{
text.SetBinding(HighLightKeyWord.InternalTextProperty, textBinding.ParentBindingBase);
}
}
...
}