In UWP or WinUI3, how to use AutoSuggestBox as the search box and highlight the matching keywords in red in the search result list

C CB 170 Reputation points
2024-06-25T01:56:14.0933333+00:00

AutoSuggestBox is a good control in WinUI3. I use it as a search box and display search results. But how to achieve more advanced functions, such as highlighting keywords in the results ( ex, one of the result is 'powered by Microsoft', and only 'Microsoft' is highlighting ). I tried to define the data template for AutoSuggestBox.ItemTemplate , binding a converted Span object data for TextBlock.Text or TextBlock.Run.Text. But none of them can work. Does anyone know how to implement this feature?

    public class SearchResultConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var returnRuns = new Span();
            Run normalRun = new Run();
            normalRun.Text = "powered by ";
            returnRuns.Inlines.Add(normalRun);
            Run highlightingRun = new Run();
            highlightingRun.Foreground = new SolidColorBrush(Microsoft.UI.Colors.Green);
            highlightingRun.Text = "Microsoft";
            returnRuns.Inlines.Add(highlightingRun);
            return returnRuns;
        }
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
<AutoSuggestBox.ItemTemplate>
    <DataTemplate> 
        <TextBlock> 
            <Run Text="{Binding NoteName, Converter={StaticResource SearchResultConverter}}"></Run>
        </TextBlock>
    </DataTemplate>
</AutoSuggestBox.ItemTemplate>
Universal Windows Platform (UWP)
Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
796 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,029 questions
{count} votes

Accepted answer
  1. Junjie Zhu - MSFT 18,966 Reputation points Microsoft Vendor
    2024-06-26T09:30:45.7866667+00:00

    Hi @C CB ,

    Welcome to Microsoft Q&A!

    I found a solution, it needs to use a Usercontrol to handle the highlight font.

    UserControl1.xaml.cs

    I define a Property highLightText in Usercontrol, and handle the string "<div>powered by <font color=red>Microsoft</font></div>". Extract string "powered by" and "Microsoft".

     public sealed partial class UserControl1 : UserControl
     {
         public static DependencyProperty highLightTextProperty = DependencyProperty.Register(
      "highLightText", typeof(string), typeof(UserControl1), new PropertyMetadata("test"));
         public string highLightText
         {
             get { return (string)GetValue(highLightTextProperty); }
             set { SetValue(highLightTextProperty, value); }
         }
         public UserControl1()
         {
             this.InitializeComponent();
             (this.Content as FrameworkElement).DataContext = this;
         }
         private void UserControl_Loaded(object sender, RoutedEventArgs e)
         {
           
             //< div > powered by < font color = red > Microsoft </ font ></ div >
             var xamlcode= this.highLightText.ToString();
             if (xamlcode.IndexOf(">")<1)
             {
                 return;
             }
             // Extract text
             int start = xamlcode.IndexOf(">") + 1;
             int end = xamlcode.IndexOf("<font");
             string extractedText = xamlcode.Substring(start, end - start);
             // Extract font color
             int colorStart = xamlcode.IndexOf("color=") + 6;
             int colorEnd = xamlcode.IndexOf(">", colorStart);
             string fontColor = xamlcode.Substring(colorStart, colorEnd - colorStart);
             // Extract company name
             int companyNameStart = xamlcode.IndexOf(fontColor+">") + fontColor.Length+1;
             int companyNameEnd = xamlcode.IndexOf("</font", companyNameStart);
             string companyName = xamlcode.Substring(companyNameStart, companyNameEnd - companyNameStart).Trim();
             var returnRuns = new Span();
             Run normalRun = new Run();
             normalRun.Text = extractedText;
             returnRuns.Inlines.Add(normalRun);
             Run highlightingRun = new Run();
             highlightingRun.Foreground = new SolidColorBrush(Microsoft.UI.Colors.Red);
             highlightingRun.Text = companyName;
             returnRuns.Inlines.Add(highlightingRun);
             txtBlock.Inlines.Clear();
             txtBlock.Inlines.Add(returnRuns);
         }
     } 
    

    UserControl1.xaml

    <UserControl
        x:Class="App1.UserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Loaded="UserControl_Loaded"
        mc:Ignorable="d">
        <Grid>
            <TextBlock x:Name="txtBlock"/>
        </Grid>
        
    </UserControl>
    

    MainWindow.xaml

      <AutoSuggestBox PlaceholderText="Search" QueryIcon="Find" Width="400"
              TextChanged="AutoSuggestBox_TextChanged"
              QuerySubmitted="AutoSuggestBox_QuerySubmitted"
              SuggestionChosen="AutoSuggestBox_SuggestionChosen">
          
              <AutoSuggestBox.ItemTemplate>
                  <DataTemplate>
                  <local:UserControl1 highLightText="{Binding }"/>
              </DataTemplate>
              </AutoSuggestBox.ItemTemplate>  
          
      </AutoSuggestBox>
    

    MainWindow.xaml.cs

     public sealed partial class MainWindow : Window
     {
         public MainWindow()
         {
             this.InitializeComponent();
         }
         public string changeHtmlToText(string xamlcode)
         {
            
             if (xamlcode.IndexOf(">") < 1)
             {
                 return "wrong";
             }
             // Extract text
             int start = xamlcode.IndexOf(">") + 1;
             int end = xamlcode.IndexOf("<font");
             string extractedText = xamlcode.Substring(start, end - start);
             // Extract font color
             int colorStart = xamlcode.IndexOf("color=") + 6;
             int colorEnd = xamlcode.IndexOf(">", colorStart);
             string fontColor = xamlcode.Substring(colorStart, colorEnd - colorStart);
             // Extract company name
             int companyNameStart = xamlcode.IndexOf(fontColor + ">") + fontColor.Length + 1;
             int companyNameEnd = xamlcode.IndexOf("</font", companyNameStart);
             string companyName = xamlcode.Substring(companyNameStart, companyNameEnd - companyNameStart).Trim();
             return extractedText + companyName;
         }
         private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
         {
             if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
             {
                 var suitableItems = new List<string>();
                 var splitText = sender.Text.ToLower().Split(" ");
                 foreach (var cat in Cats)
                 {
                     var found = splitText.All((key) =>
                     {
                         return cat.ToLower().Contains(key);
                     });
                     if (found)
                     {
                         suitableItems.Add(cat);
                     }
                 }
                 if (suitableItems.Count == 0)
                 {
                     suitableItems.Add("No results found");
                 }
                 sender.ItemsSource = suitableItems;
             }
         }
         private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
         {
             
             sender.Text = changeHtmlToText(args.SelectedItem.ToString());
         }
         private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
         {
             if (args.ChosenSuggestion != null)
             {
                 // User selected an item from the suggestion list, take an action on it here.
             }
             else
             {
                 // Use args.QueryText to determine what to do.
             }
         }
         private List<string> Cats = new List<string>()
         {
             "<div>powered by <font color=red>Microsoft</font></div>",
             "<div>copy by <font color=red>Microsoft</font></div>",
             "<div>publish <font color=red>Azure</font></div>",
             "<div>Hello <font color=red>World</font></div>"
            
         };
    

    User's image

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.