我正在尝试突出显示给定范围内的换行文本。我可以实现预期的行为。如果搜索文本是单行,并且搜索文本以两行(换行)呈现,如下所示,我将面临问题,
我使用了字符范围和MeasureCharacterRanges方法来查找文本区域的区域,并排除了与给定搜索文本不匹配的文本区域,但我找不到没有文本的空白区域的区域渲染后,空白区域也会与给定的搜索文本一起突出显示。
StringFormat stringFormat = new StringFormat(StringFormat.GenericDefault);
Font font = new Font("Segoe UI", 9F, FontStyle.Regular);
var searchText = string.IsNullOrEmpty(SearchText) ? string.Empty : SearchText;
int matchIndex = Text.IndexOf(searchText);
if (matchIndex != -1 && searchText.Length > 0)
{
CharacterRange[] characterRange = new CharacterRange[]
{
new CharacterRange(0, matchIndex),
new CharacterRange(matchIndex, searchText.Length),
new CharacterRange(matchIndex + searchText.Length , Text.Length - matchIndex - searchText.Length),
};
//Set the range of characters to be measured.
stringFormat.SetMeasurableCharacterRanges(characterRange);
//Gets the regions of the measurable characters applied to the string format for the given text with in the text bounds.
Region[] regions = e.Graphics.MeasureCharacterRanges(Text, font, e.ClipRectangle, stringFormat);
var clipBounds = e.Graphics.ClipBounds;
for (int i = 0; i < regions.Length; i++)
{
RectangleF bound = regions[i].GetBounds(e.Graphics);
e.Graphics.SetClip(Rectangle.Ceiling(bound));
for (int j = 0; j < regions.Length; j++)
{
if (j != i)
e.Graphics.ExcludeClip(regions[j]);
}
Rectangle rbound = new Rectangle((int)bound.X, (int)bound.Y, (int)bound.Width, (int)bound.Height);
Brush brush = new SolidBrush(Color.Yellow);
if (i == 1)
e.Graphics.FillRectangle(brush, rbound);
}
e.Graphics.SetClip(clipBounds);
}
// Paints the text.
e.Graphics.DrawString(Text, font, Brushes.Black, e.ClipRectangle);
上面是用于突出显示搜索文本的代码。
我找不到用 MeasureCharacterRanges 概念排除空白区域的方法。 任何人都可以分享排除剩余空白区域的想法吗?
此代码将帮助您
if (SelectionLength > 0 && Focused)
{
// Get the starting index and length of the selection
int selectionStartIndex = SelectionStart;
int selectionEndIndex = selectionStartIndex + SelectionLength; // Calculate the end index of the selection
int selectedTextLength = this.SelectionLength;
int OneCharSize = (int)TextRenderer.MeasureText("..", Font).Width;
// int OneCharSize = (int)TextRenderer.MeasureText("..", new Font("Tahoma", Font.Size)).Width;
// Loop through each selected character to draw the background
for (int i = selectionStartIndex; i < selectionEndIndex; i++)
{
// Check if the current character is a newline character
if (Text[i] == '\n' || Text[i] == '\r')
{
continue; // Skip drawing for newline characters
}
// Get the position of the character at the current index
Point charPosition = GetPositionFromCharIndex(i);
// Get the size of the character at the current index
Size charSize = TextRenderer.MeasureText(Text[i].ToString(), Font);
// Create a rectangle using the position and size of the character
Rectangle charRect = new Rectangle(charPosition.X, charPosition.Y, charSize.Width - OneCharSize / 2, charSize.Height);
// Draw the selection background for the current character
//using (SolidBrush selectionBrush = new SolidBrush(Color.FromArgb(100, SystemColors.Highlight)))
using (SolidBrush selectionBrush = new SolidBrush(highlightColor))
{
e.Graphics.FillRectangle(selectionBrush, charRect);
}
}
}