Если ObjectListView поддерживает его (нормальный ListView, конечно же)), просто используйте TextRenderer
для рисования текста:
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;
TextRenderer.DrawText(e.Graphics, e.Item.Text, Font, e.Bounds,
Color.Blue, Color.LightSteelBlue, flags);
}
Как обычно только один стиль поддерживается за вызов. Поэтому, чтобы выделить определенные слова, вы будете использовать более одного вызова, а также использовать метод TextRenderer.MeasureText
для поиска следующих позиций. Это будет довольно трудно получить этот пиксель-идеальным, если вы не можете согласиться с фиксированным шрифтом ..
Вот быстрый и грязный пример:
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
TextFormatFlags flags = TextFormatFlags.Left;
int leftPadding = 3;
int x = leftPadding;
var words = e.Item.Text.Split('#');
for (int i = 0; i < words.Count(); i++)
{
Point pt = new Point(x, e.Bounds.Top);
Size sz = TextRenderer.MeasureText(words[i], Font);
if (i % 2 == 0)
TextRenderer.DrawText(e.Graphics, words[i], Font, pt,
Color.Black, flags);
else
TextRenderer.DrawText(e.Graphics, words[i], Font, pt,
Color.Blue, Color.LightSteelBlue, flags);
x += sz.Width;
}
}
Как вы можете см., после щелей есть дополнительное пространство. Может быть, с помощью E.Graphics.MeasureString
вызова WIH на StringFormat.GenericTypographic
будет лучше, так как он настроен на создание размеров без слабины ..:
Update:
Это выглядит лучше, что делает нас обоих рендереров:
Point pt = new Point(x, e.Bounds.Top);
Size sz1 = TextRenderer.MeasureText(words[i], Font);
SizeF sz2 = e.Graphics.MeasureString(words[i],Font, 9999, StringFormat.GenericTypographic);
if (i % 2 == 0)
TextRenderer.DrawText(e.Graphics, words[i], Font, pt, Color.Black);
else
TextRenderer.DrawText(e.Graphics, words[i], Font, pt,
Color.Blue, Color.LightSteelBlue);
x += (int)(sz1.Width + sz2.Width)/2;
чтобы нарисовать завернутые текст нужно взять доступное пространство в соотв ount и включить координату y в расчет. Для этого вы можете либо нарисовать слово за словом, либо использовать перегрузку RenderText
, которая принимает Rectangle
. Это будет получить довольно утомительно!
Update 2
Вот еще один быстрый один, показывающий, как обрабатывать оберточной текст:
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
int maxW = e.Bounds.Width;
int leftPadding = 3;
int leading = 1;
int x = leftPadding;
int y = e.Bounds.Y;
var chunks = e.Item.Text.Split('#');
SizeF s0 = e.Graphics.MeasureString("_|", Font);
Size s1 = e.Bounds.Size;
for (int i = 0; i < chunks.Count(); i++)
{
Point pt = new Point(x, e.Bounds.Top);
var words = chunks[i].Split(' ');
for (int j = 0; j < words.Count(); j++)
{
Size sz1 = TextRenderer.MeasureText(words[j], Font);
SizeF sz2 = e.Graphics.MeasureString(words[j], Font, 9999,
StringFormat.GenericTypographic);
int w = (int)(sz1.Width + sz2.Width)/2;
if (x + w > maxW)
{
y += sz1.Height + leading;
x = leftPadding;
}
DrawWords(e.Graphics, words[j], Font, new Point(x, y),
Color.Blue, Color.LightSteelBlue, i % 2 != 1);
x += w;
}
}
}
Он использует небольшую функцию:
void DrawWords(Graphics g, string text, Font font, Point pt,
Color fCol, Color Bcol, bool highlite)
{
if (highlite)
TextRenderer.DrawText(g, text, font, pt, Color.Black);
else
TextRenderer.DrawText(g, text, font, pt, Color.Blue, Color.LightSteelBlue);
}
Спасибо, но текст завернут, как в exa mple в ссылке в моем вопросе. – Jerry