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));
}
  • Вопрос задан
  • 461 просмотр
Решения вопроса 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
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы