gpt4 book ai didi

.net - WPF Listbox 突出显示 ListBoxItem 元素的一部分

转载 作者:行者123 更新时间:2023-12-01 09:11:18 40 4
gpt4 key购买 nike

我有一个文本框和列表框。用户可以从 TextBox 中搜索 ListBox 元素。

ListBox 绑定(bind)到 CollectionViewSource。

CollectionViewSource 具有 Filter 事件处理程序,它根据用户在 TextBox 中输入的文本过滤元素。

我的要求是在 ListBoxItem 元素的 TextBlock 中突出显示用户输入的文本。

我正在考虑将 TextBlock 分解为几个 Runs 对象并修改需要突出显示的 Run 对象的 Background 属性。

我认为不可能使用 DataTemplates。

有没有简单的方法可以做到这一点?

谢谢!

最佳答案

更新:我在 this blog post 中详细阐述了这个主题。 .

我不认为有任何简单的方法可以做到这一点,但这是我解决这个问题的方法:

  1. 为列表中的项目定义 View 模型。它应该包含一些属性来显示文本并定义应该突出显示文本的哪一部分(基本上是开始和结束索引)。
  2. 当用户在搜索框中输入文本时,查看 View 模型并检查文本中的匹配项。如果找到匹配项,请适当设置索引。如果未找到匹配项,请将索引设置回 -1 或任何表示不匹配的值。
  3. 在您的 View 中,将 TextBlockBackground 设置为索引。使用转换器将索引转换为 GradientBrush 在两个索引之间呈亮黄色(或其他)。

我认为您可以通过以下方式计算出 TextBlock 突出显示部分的尺寸:

  1. 通过 TextBlock.ContentStart 属性获取 TextPointer
  2. 通过使用 LogicalDirection.Forwards 调用 TextPointer.GetPositionAtOffset(indexOfStart) 移动到选择的开头。
  3. 通过使用 LogicalDirection.Backwards 调用 TextPointer.GetPositionAtOffset(indexOfStart) 移动到选择的末尾。
  4. 调用TextPointer.GetCharacterRect获取高亮内容的边界Rectangle

说实话,我不确定最后一点是否有效。我必须自己尝试一下,我可能会为博客文章这样做。

编辑:刚刚有时间亲自尝试一下。它确实有效,尽管我上面的逻辑略有改变。下面是演示的代码。截图如下:

Screenshot http://img219.imageshack.us/img219/2969/searchx.png

Window1.xaml:

<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>

Window1.xaml.cs:

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);
}
}
}
}

我认为代码是不言自明的。显然,您需要将该概念扩展到您的特定场景。您可能更喜欢将 TextBlockBackground 属性与 DrawingBrushGradientBrush 结合使用,而不是使用单独的路径.

关于.net - WPF Listbox 突出显示 ListBoxItem 元素的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/798579/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com