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
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: HighlightText, HighlightTextColor, HighlightCompareOptions. 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