我有一个TextBox和ListBox。用户可以从TextBox中搜索ListBox元素。
ListBox绑定到CollectionViewSource。
CollectionViewSource具有Filter事件处理程序,可根据用户输入TextBox的文本过滤元素。
我的要求是突出显示用户在ListBoxItem元素的TextBlock中输入的文本。
我正在考虑将TextBlock分成几个Runs对象,并修改需要突出显示的Run对象的Background属性。
我认为不可能使用DataTemplates。
有没有简单的方法来实现这个目标?
谢谢!
答案 0 :(得分:9)
更新:我在this blog post中详细阐述了这个主题。
我认为没有任何简单的方法可以做到这一点,但这是我将如何解决这个问题:
Background
的{{1}}设置为索引。使用转换器将索引转换为两个索引之间为亮黄色(或其他)的TextBlock
。以下是我认为的方法,您可以找出GradientBrush
突出显示部分的尺寸:
TextBlock
媒体资源获取TextPointer
。TextBlock.ContentStart
TextPointer.GetPositionAtOffset(indexOfStart)
,转到选择的开头
LogicalDirection.Forwards
TextPointer.GetPositionAtOffset(indexOfStart)
,移至选择的末尾
LogicalDirection.Backwards
以获取突出显示内容的边界TextPointer.GetCharacterRect
。说实话,我不确定最后一点是否有效。我必须自己尝试一下,我可以为博客发帖。
编辑:有时间为自己试一试。它确实有效,尽管我的逻辑略有改变。下面是演示的代码。这是一个截图:
Screenshot http://img219.imageshack.us/img219/2969/searchx.png
Window1.xaml :
Rectangle
Window1.xaml.cs :
<Window x:Class="TextSearch.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1">
<StackPanel>
<TextBox x:Name="_searchTextBox"/>
<Grid>
<Path Fill="Yellow" Stroke="Black" StrokeThickness="0">
<Path.Data>
<RectangleGeometry x:Name="_rectangleGeometry"/>
</Path.Data>
</Path>
<TextBlock x:Name="_textBlock">Some sample text that you can search through by typing in the above TextBox.</TextBlock>
</Grid>
</StackPanel>
</Window>
我认为代码是相当不言自明的。显然,您需要将概念扩展到您的特定场景。您可能更愿意利用using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace TextSearch
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
_searchTextBox.TextChanged += _searchTextBox_TextChanged;
}
void _searchTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var searchText = _searchTextBox.Text;
var index = _textBlock.Text.IndexOf(searchText);
if (index == -1)
{
_rectangleGeometry.Rect = Rect.Empty;
}
else
{
var textPointer = _textBlock.ContentStart;
textPointer = textPointer.GetPositionAtOffset(index + 1, LogicalDirection.Forward);
var leftRectangle = textPointer.GetCharacterRect(LogicalDirection.Forward);
textPointer = textPointer.GetPositionAtOffset(searchText.Length, LogicalDirection.Backward);
var rightRectangle = textPointer.GetCharacterRect(LogicalDirection.Forward);
_rectangleGeometry.Rect = new Rect(leftRectangle.TopLeft, rightRectangle.BottomRight);
}
}
}
}
的{{1}}属性与Background
或TextBlock
相结合,而不是使用单独的DrawingBrush
。
答案 1 :(得分:0)
在WPF列表框中过滤。 以下示例代码对我来说很好。
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<TextBox Name="txtSearch" Height="21" Margin="63,12,12,0" VerticalAlignment="Top"></TextBox>
<ListBox Name="listItems" ItemsSource="{Binding}" Margin="22,0,0,44" Height="179" VerticalAlignment="Bottom" />
</Grid>
Vb.net代码
将数据表绑定到列表框
Dim _dtable As New DataTable("tblItems") _dtable.Columns.Add("Id", GetType(Integer))
_dtable.Columns.Add("Name", GetType(String))
_dtable.Columns.Add("Price", GetType(Double))
' Add any initialization after the InitializeComponent() call.
For i = 100 To 110
_dtable.Rows.Add(i, "Item " & i, 15.0)
Next
Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
listItems.DataContext = _dtable.DefaultView
End Sub
Private Sub txtSearch_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.TextChangedEventArgs) Handles txtSearch.TextChanged
_dtable.DefaultView.RowFilter =“Name like'”&amp; txtSearch.Text&amp; “%'”强>
End Sub
以上示例代码适用于我