This is a migrated thread and some comments may be shown as answers.

How to highlight the matched text part of filtered node?

3 Answers 129 Views
Treeview
This is a migrated thread and some comments may be shown as answers.
Steve
Top achievements
Rank 1
Veteran
Steve asked on 11 Jan 2020, 12:21 PM

I want to implement the effect that highlight the matched text part of filtered node. The visual effect is just like the solution manager of visual studio. How can I do it? Thanks!

 

3 Answers, 1 is accepted

Sort by
0
Steve
Top achievements
Rank 1
Veteran
answered on 14 Jan 2020, 02:05 AM
Can anyone else know how to do that?
0
Accepted
Todor
Telerik team
answered on 14 Jan 2020, 09:33 AM

Hi Steve,

The desired text highlight effect can be achieved by setting the TextParams highlightRanges and highlightColor properties just before the paint cycle of TreeNodeContentElement
I have prepared a code sample below.

First, we need to create a custom TreeNodeElement by subscribing to the CreateNodeElement event of RadTreeView.

private void RadTreeView1_CreateNodeElement(object sender, CreateTreeNodeElementEventArgs e)
{
    e.NodeElement = new HighlightTreeNodeElement();
}

The custom TreeNodeElement has three main highlight related properties: HighlightTextHighlightTextColorHighlightCompareOptions. It has also a custom TreeNodeContentElement(this is the element that holds the text).

public class HighlightTreeNodeElement : TreeNodeElement
{
    public static string HighlightText { get; set; }

    public static Color HighlightTextColor { get; set; }

    public static CompareOptions HighlightCompareOptions { get; set; }

    static HighlightTreeNodeElement()
    {
        HighlightText = string.Empty;
        HighlightTextColor = Color.FromArgb(128, Color.Yellow);
        HighlightCompareOptions = CompareOptions.OrdinalIgnoreCase;
    }

    protected override Type ThemeEffectiveType
    {
        get { return typeof(TreeNodeElement); }
    }

    protected override TreeNodeContentElement CreateContentElement()
    {
        HighlightTreeNodeContentElement contentElement = new HighlightTreeNodeContentElement();
        contentElement.ShouldHandleMouseInput = false;
        return contentElement;
    }
}

To modify the TextParams of TreeNodeContentElement we need to override the CreateTextParams method and there we can add our hightlightRanges and set the highlightColor. The GetSearchHighlightRanges method is responsible for creating the highlightRanges and considers the HightlightText and HighlightCompareOptions.

public class HighlightTreeNodeContentElement : TreeNodeContentElement
{
    protected override Type ThemeEffectiveType
    {
        get { return typeof(TreeNodeContentElement); }
    }

    protected override TextParams CreateTextParams()
    {
        TextParams textParams = base.CreateTextParams();
        if (!string.IsNullOrEmpty(HighlightTreeNodeElement.HighlightText))
        {
            List<CharacterRange> ranges = this.GetSearchHighlightRanges();
            if (ranges.Count > 0)
            {
                textParams.highlightRanges = ranges.ToArray();
                textParams.highlightColor = HighlightTreeNodeElement.HighlightTextColor;
            }
        }

        return textParams;
    }

    private List<CharacterRange> GetSearchHighlightRanges()
    {
        List<CharacterRange> ranges = new List<CharacterRange>();
        string criteria = HighlightTreeNodeElement.HighlightText;

        int index = -1;
        CompareOptions options = HighlightTreeNodeElement.HighlightCompareOptions;
        string text = this.Text;
        do
        {
            if (index + 1 >= text.Length)
            {
                break;
            }

            index = System.Threading.Thread.CurrentThread.CurrentUICulture.CompareInfo.IndexOf(text, criteria, index + 1, options);

            if (index >= 0)
            {
                if ((options & CompareOptions.IgnoreSymbols) == CompareOptions.IgnoreSymbols)
                {
                    int rangeLength = 0;
                    int criteriaLength = criteria.Length;
                    int currentIndex = index;

                    while (criteriaLength > 0 && currentIndex < text.Length)
                    {
                        if (Char.IsLetterOrDigit(text[currentIndex]))
                        {
                            criteriaLength--;
                        }

                        rangeLength++;
                        currentIndex++;
                    }

                    ranges.Add(new CharacterRange(index, rangeLength));
                }
                else
                {
                    ranges.Add(new CharacterRange(index, criteria.Length));
                }
            }

        } while (index >= 0 && ranges.Count < 32);

        return ranges;
    }
}

Last, but not least we need to update the HighlightText when the text of a text box is changed and force the RadTreeView to repaint.

private void radTextBox1_TextChanged(object sender, EventArgs e)
{
    HighlightTreeNodeElement.HighlightText = this.radTextBox1.Text;
    this.radTreeView1.Refresh();
}

You can see the result on my end in the attached image.

Note that this is just a sample approach and it may not cover all possible cases. Feel free to modify and extend it in a way that suits your requirements best.

I hope this information helps. If you need any further assistance please don't hesitate to contact me.

Regards,
Todor Vyagov
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Steve
Top achievements
Rank 1
Veteran
answered on 14 Jan 2020, 12:13 PM
It seems a little complicated. Great thanks for your detailed reply and its help me a lot!
Tags
Treeview
Asked by
Steve
Top achievements
Rank 1
Veteran
Answers by
Steve
Top achievements
Rank 1
Veteran
Todor
Telerik team
Share this question
or