how to highlight searched text in DataGrid Cells on WinUI 3 application. Or how to use RichTextBlock in the Datagrid cell?

EdgeMac 20 Reputation points
2024-09-10T14:50:55.9+00:00

how to highlight searched text in DataGrid Cells on WinUI 3 application. Or how to use RichTextBlock in the Datagrid cell?

I'm writing a C# WinUI 3 Desktop App with DataGrid. And I want to use rich text in the DataGird cell to highlight the searched text. How should I do in the next?

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
11,561 questions
Windows
Windows
A family of Microsoft operating systems that run across personal computers, tablets, laptops, phones, internet of things devices, self-contained mixed reality headsets, large collaboration screens, and other devices.
5,376 questions
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.
784 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.
10,899 questions
Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
9,580 questions
0 comments No comments
{count} votes

Accepted answer
  1. Junjie Zhu - MSFT 17,806 Reputation points Microsoft Vendor
    2024-09-11T07:31:29.4266667+00:00

    Hi @EdgeMac ,

    Welcome to Microsoft Q&A!

    Using VisualTreeHelper, we can find that the text elements in DataGrid are stored in TextBlock. We can use VisualTreeHelper to read all TextBlocks in DataGrid and highlight the text we want. This example is just a simple demonstration and can only find the first matching text. You need to continue to improve it.

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBox x:Name="searchTextBox" Text="Banner"></TextBox>
        <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
        <controls:DataGrid x:Name="EmployeeGrid"
                    ItemsSource="{x:Bind Persons}"
                    AutoGenerateColumns="False">
            <controls:DataGrid.Columns>
                <controls:DataGridTextColumn Header="First Name"
                                                Binding="{Binding FirstName}"/>
                <controls:DataGridTextColumn Header="Last Name"
                                                Binding="{Binding LastName}"/>
                <controls:DataGridTextColumn Header="Position"
                                                Binding="{Binding Position}"/>
                <!--<controls:DataGridTemplateColumn  Header="First Name">
                    <controls:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding FirstName}"/>
                        </DataTemplate>
                    </controls:DataGridTemplateColumn.CellEditingTemplate>
                </controls:DataGridTemplateColumn>-->
                    
            </controls:DataGrid.Columns>
        </controls:DataGrid>
    
     public sealed partial class MainWindow : Window
    {
        public List<Department> Departments { get; set; }
        public List<Person> Persons { get; set; }
        public MainWindow()
        {
            this.InitializeComponent();
            Departments = new List<Department>
            {
                new Department {DepartmentId = 1, DepartmentName = "R&D"},
                new Department {DepartmentId = 2, DepartmentName = "Finance"},
                new Department {DepartmentId = 3, DepartmentName = "IT"}
            };
            Persons = new List<Person>
            {
                new Person
                {
                    PersonId = 1, DepartmentId = 3, FirstName = "Ronald", LastName = "Rumple",
                    Position = "Network Administrator"
                },
                new Person
                {
                    PersonId = 2, DepartmentId = 1, FirstName = "Brett", LastName = "Banner",
                    Position = "Software Developer"
                },
                new Person
                {
                    PersonId = 3, DepartmentId = 2, FirstName = "Alice", LastName = "Anderson",
                    Position = "Accountant"
                }
            };
        }
        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            myButton.Content = "Clicked";
            var searchString= searchTextBox.Text.Trim();
            List<TextBlock> txtBlocklist = new List<TextBlock>();
            FindChildren(txtBlocklist, EmployeeGrid);
            foreach (TextBlock txtBlock in txtBlocklist)
            {
                txtBlock.TextHighlighters.Clear();
                int index = txtBlock.Text.IndexOf(searchString);
                if (index >= 0 )
                {
                    TextRange textRange = new TextRange() { StartIndex = index, Length = searchString.Length };
                    TextHighlighter highlighter = new TextHighlighter()
                    {
                        Background = new SolidColorBrush(Colors.Yellow),
                        Ranges = { textRange }
                    };
                    //add the highlighter
                    txtBlock.TextHighlighters.Add(highlighter);
                }
                   
            }
        }
        internal static void FindChildren<T>(List<T> results, DependencyObject startNode) where T : DependencyObject
        {
            int count = VisualTreeHelper.GetChildrenCount(startNode);
            for (int i = 0; i < count; i++)
            {
                DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
                if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
                {
                    T asType = (T)current;
                    results.Add(asType);
                }
                FindChildren<T>(results, current);
            }
        }
    }
    //backing data source in MyViewModel
    public class Department
    {
        public int DepartmentId { get; set; }
        public string DepartmentName { get; set; }
    }
    public class Person
    {
        public int PersonId { get; set; }
        public int DepartmentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Position { get; set; }
    }   
    

    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.


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.