更新: この件については、このブログ投稿で詳しく説明しました。
これを行う簡単な方法はないと思いますが、この問題に取り組む方法は次のとおりです。
- リスト内の項目のビュー モデルを定義します。テキストを公開し、テキストのどの部分を強調表示するかを定義するプロパティを含める必要があります (基本的には開始インデックスと終了インデックス)。
- ユーザーが検索ボックスにテキストを入力したら、ビュー モデルを調べて、テキスト内の一致を確認します。一致が見つかった場合は、インデックスを適切に設定します。一致するものが見つからない場合は、インデックスを -1 に戻すか、一致しないことを示す値に戻します。
- ビューで、 の をインデックスに設定
Background
しTextBlock
ます。GradientBrush
コンバーターを使用して、インデックスを2 つのインデックス間の明るい黄色 (またはその他)に変換します。
の強調表示された部分の寸法を把握する方法は次のとおりですTextBlock
。
TextPointer
プロパティ経由で取得しTextBlock.ContentStart
ます。
TextPointer.GetPositionAtOffset(indexOfStart)
を使用して呼び出して、選択の先頭に移動しLogicalDirection.Forwards
ます。
TextPointer.GetPositionAtOffset(indexOfStart)
を使用して呼び出して、選択範囲の最後に移動しLogicalDirection.Backwards
ます。
- 強調表示されたコンテンツ
TextPointer.GetCharacterRect
の境界を取得するために呼び出します。Rectangle
正直なところ、最後のビットが機能するかどうかはわかりません。私は自分でそれを試してみる必要があり、ブログ投稿のためにそれを行うかもしれません.
編集:これを自分で試す時間がありました。上記の私のロジックにわずかな変更を加えましたが、間違いなく機能します。以下は、実証するコードです。スクリーンショットは次のとおりです。
スクリーンショット 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);
}
}
}
}
コードはかなり自明だと思います。明らかに、この概念を特定のシナリオに拡張する必要があります。個別の を使用する代わりに、またはと組み合わせた のBackground
プロパティを活用することをお勧めします。TextBlock
DrawingBrush
GradientBrush
Path