Задать вопрос
Volgarastraport
@Volgarastraport

[C#] Как работать с MeasureString в цикле?

Мне нужно нарисовать в картинку список заголовков с иконками.
5aa61b848dc87027993097.png
Но т. к. заголовки имеют разную длину, то получаются или большие пропуски или текст накладывается друг на друга.
Пытаюсь в цикле сохранять размер предыдущего блока и сдвигать следующий, но всё равно накладки происходят.
Примеров в сети не много, может здесь кто подскажет.
Bitmap bmp3 = null;
string str = "";
int step = (int) (s*0.2);
SizeF layoutSize = new SizeF((float)(w*0.5), (float)(s*0.2));
SizeF textSize = new SizeF();
for (int i = 0; i < list2.Count && i < 5; i++) {
	str = list2[i];
	textSize = grp.MeasureString(str, font, layoutSize);
	grp.DrawString(str, font, brush, new RectangleF(60, 20 + step, (int)(w*0.5)-50, step), stringFormat); //заголовок
	step = step + (int) textSize.Height;
	bmp3 = (Bitmap) Image.FromFile(list3[i], true); // иконка 
	grp.DrawImage(bmp3, 10, 25 + step, (int) (bmp3.Width * 0.25), (int) (bmp3.Height * 0.25));
}
  • Вопрос задан
  • 507 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
alexsandr0000
@alexsandr0000
Программист C#/C++/C
Можно попробовать вычислить число строк:
private int GetNumOfLines(string multiPageString, int wrapWidth, Font fnt)
{
        var sfFmt = new StringFormat(StringFormatFlags.LineLimit);
        using(var g = Graphics.FromImage(New Bitmap(1, 1)))
       {
            var iHeight = g.MeasureString(multiPageString, fnt, wrapWidth, sfFmt).Height;
            var iOneLineHeight = g.MeasureString("Z", fnt, wrapWidth, sfFmt).Height;
            return (int)(iHeight / iOneLineHeight)
        }
}

И умножить на высоту шрифта
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@cicatrix
было бы большой ошибкой думать
Ещё хинт: в простых случаях, можно MeasureString не вызывать а воспользоваться свойством Height самого шрифта.
Из примера выше вот это:
var iOneLineHeight = g.MeasureString("Z", fnt, wrapWidth, sfFmt).Height;

эквивалентно этому:
var iOneLineHeight = fnt.Height;

Вопрос ещё такой - вы где всё это отрисовываете? WPF, Winforms? Системный оконный менеджер для этих целей сам может всё рассчитать. Float Container с ограничением по длине, а внутри набор Label с Autosize, в принципе, избавят вас от этих мучений.

Имейте так же в виду, что MeasureString не гарантирует вам точных замеров ширины текста. Чтобы всё рассчитать точно, надо пользоваться MeasureCharacterRanges
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы