我有一个TextBox和一个用于搜索数据集合的列表框。在列表框中搜索文本时,如果在列表中的任何位置找到匹配的字符串,它应该以粗体显示为粗体。
例如。我有像字符串集合 “依赖属性,自定义属性,正常属性”。如果我在搜索文本框中输入“prop”,那么所有带有“prop”的三个(只有单词Prop)应该是粗体,其颜色应该是绿色。知道如何做到这一点?
列表框中的数据使用DataTemplate表示。
答案 0 :(得分:8)
我创建了一个HighlightTextBehavior,您可以将其附加到列表项模板中的TextBlock(您需要在项目中添加对System.Windows.Interactivity的引用)。将行为绑定到包含要突出显示的文本的属性,然后执行其余操作。
目前,它只突出显示字符串的第一个实例。它还假定没有其他格式应用于文本。
using System.Linq;
using System.Text;
using System.Windows.Interactivity;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace StringHighlight
{
public class HighlightTextBehavior : Behavior<TextBlock>
{
public string HighlightedText
{
get { return (string)GetValue(HighlightedTextProperty); }
set { SetValue(HighlightedTextProperty, value); }
}
// Using a DependencyProperty as the backing store for HighlightedText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HighlightedTextProperty =
DependencyProperty.Register("HighlightedText", typeof(string), typeof(HighlightTextBehavior), new UIPropertyMetadata(string.Empty, HandlePropertyChanged));
private static void HandlePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
(sender as HighlightTextBehavior).HandlePropertyChanged();
}
private void HandlePropertyChanged()
{
if (AssociatedObject == null)
{
return;
}
var allText = GetCompleteText();
AssociatedObject.Inlines.Clear();
var indexOfHighlightString = allText.IndexOf(HighlightedText);
if (indexOfHighlightString < 0)
{
AssociatedObject.Inlines.Add(allText);
}
else
{
AssociatedObject.Inlines.Add(allText.Substring(0, indexOfHighlightString));
AssociatedObject.Inlines.Add(new Run() {
Text = allText.Substring(indexOfHighlightString, HighlightedText.Length),
Foreground = Brushes.Green,
FontWeight = FontWeights.Bold });
AssociatedObject.Inlines.Add(allText.Substring(indexOfHighlightString + HighlightedText.Length));
}
}
private string GetCompleteText()
{
var allText = AssociatedObject.Inlines.OfType<Run>().Aggregate(new StringBuilder(), (sb, run) => sb.Append(run.Text), sb => sb.ToString());
return allText;
}
}
}
以下是您如何使用它的示例:
<Window x:Class="StringHighlight.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:b="clr-namespace:StringHighlight"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<x:Array x:Key="MyStrings" Type="{x:Type sys:String}">
<sys:String>This is my first string</sys:String>
<sys:String>Another string</sys:String>
<sys:String>A third string, equally imaginative</sys:String>
</x:Array>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox x:Name="SearchText"/>
<ListBox Grid.Row="1" ItemsSource="{StaticResource MyStrings}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Grid.Row="1" Text="{Binding}">
<i:Interaction.Behaviors>
<b:HighlightTextBehavior HighlightedText="{Binding ElementName=SearchText, Path=Text}"/>
</i:Interaction.Behaviors>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>