Может ли результат поиска TextHighlighter или TextRange быть привязан к DataTemplate в UWP XAML? - PullRequest
0 голосов
/ 06 января 2020

У меня есть класс SearchResult, который связывается с ListView. Что я хочу сделать, это выделить фрагмент текста в результатах поиска, который соответствует запросу, введенному пользователем.

Соответствующий XAML выглядит примерно так (без пуха):

<DataTemplate>
   <StackPanel>
      <!-- Search result -->
      <RichTextBlock>
         <!-- Would this idea work? -->
         <RichTextBlock.TextHighlighters>
            <TextHighlighter>
               <TextHighlighter.Ranges>
                  <!-- Add the bound range here-->
                  <!-- {Binding Range} or text highlighter or something -->
               </TextHighlighter.Ranges>
            </TextHighlighter>
         </RichTextBlock.TextHighlighters>
         <Paragraph>
            <Run Text="{Binding Text}"></Run>
         </Paragraph>
      </RichTextBlock>
   </StackPanel>
</DataTemplate>

Я могу добавить любое свойство из класса SearchResult, будь то TextHighlighter или TextRange. Я просто не знаю, позволяет ли синтаксис XAML включить это значение.

Я тоже думал сделать это в коде, но я хочу сохранить шаблон элемента поиска внутри XAML, а не помещать это в C#. Тем не менее, было бы возможно сделать что-то вроде lvSearchResults.Items[i]... или что-то еще, чтобы поместить в маркер или диапазон. Я просто не могу найти правильный метод в данный момент.

1 Ответ

2 голосов
/ 06 января 2020

Если вы планируете создать локально подсвеченный список результатов поиска, вы можете попробовать это следующим образом:

  1. Создать класс результатов поиска
public class SearchResult
{
    public string DisplayText { get; set; }
    public string HighlightText { get; set; }
}
Создать UserControl, чтобы показать результат

SearchResultBlock.xaml

<Grid>
    <TextBlock x:Name="ResultBlock" TextWrapping="Wrap" MaxLines="2"
               TextTrimming="CharacterEllipsis"/>
</Grid>

SearchResultBlock.xaml.cs

public sealed partial class SearchResultBlock : UserControl
{
    public SearchResultBlock()
    {
        this.InitializeComponent();
    }


    public SearchResult Result
    {
        get { return (SearchResult)GetValue(ResultProperty); }
        set { SetValue(ResultProperty, value); }
    }

    public static readonly DependencyProperty ResultProperty =
        DependencyProperty.Register("Result", typeof(SearchResult), typeof(SearchResultBlock), new PropertyMetadata(null,new PropertyChangedCallback(Result_Changed

    private static void Result_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if(e.NewValue!=null && e.NewValue is SearchResult data)
        {
            var instance = d as SearchResultBlock;
            instance.ResultBlock.Inlines.Clear();
            var sp = data.DisplayText.Split(data.HighlightText);
            instance.ResultBlock.Inlines.Add(new Run { Text = sp.First() });
            instance.ResultBlock.Inlines.Add(new Run { Text = data.HighlightText, Foreground = new SolidColorBrush(Colors.Red) });
            if (sp.Length > 1)
                instance.ResultBlock.Inlines.Add(new Run { Text = sp.Last() });
        }
    }
}
Используйте его в DataTemplate
<DataTemplate x:DataType="SearchResult" x:Key="ResultItemTemplate">
    <SearchResultBlock Result="{Binding}"/>
</DataTemplate>

Путем разделения строк создайте различные типы Run s и объедините их в TextBlock. Это также может обеспечить эффект выделения.

С уважением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...