Измерить строку без использования графического объекта?
Вопрос
Я использую пиксели в качестве единицы для моего шрифта. В одном месте я выполняю тест на попадание, чтобы проверить, нажал ли пользователь внутри ограничительного прямоугольника какого-либо текста на экране. Мне нужно использовать что-то вроде MeasureString
для этого. К сожалению, код, выполняющий тест на попадание, находится глубоко внутри библиотеки, которая не имеет доступа к объекту Graphics
или даже к Control
.
Как получить ограничивающий прямоугольник строки с заданным шрифтом без использования класса Graphics
? Зачем мне даже объект Graphics
, если мой шрифт в пикселях?
Решение
Если у вас есть ссылка на System.Windows.Forms, попробуйте использовать класс TextRenderer. Есть статический метод (MeasureText), который принимает строку и шрифт и возвращает размер. ссылка MSDN
Другие советы
Вам не нужно использовать графический объект, который вы используете для визуализации, для измерения. Вы можете создать статический служебный класс:
public static class GraphicsHelper
{
public static SizeF MeasureString(string s, Font font)
{
SizeF result;
using (var image = new Bitmap(1, 1))
{
using (var g = Graphics.FromImage(image))
{
result = g.MeasureString(s, font);
}
}
return result;
}
}
Возможно, в зависимости от вашей ситуации стоит также установить dpi для растрового изображения.
MeasureString
в ответе @NerdFury даст большую ширину строки, чем ожидалось. Дополнительную информацию вы можете найти в здесь . Если вы хотите измерить только физическую длину, добавьте эти две строки:
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
result =
g.MeasureString(measuredString, font, int.MaxValue, StringFormat.GenericTypographic);
Этот пример отлично иллюстрирует использование FormattedText. FormattedText обеспечивает низкоуровневое управление для рисования текста в приложениях Windows Presentation Foundation (WPF). Вы можете использовать его для измерения ширины строки с определенным шрифтом без использования графического объекта.
public static float Measure(string text, string fontFamily, float emSize)
{
FormattedText formatted = new FormattedText(
item,
CultureInfo.CurrentCulture,
System.Windows.FlowDirection.LeftToRight,
new Typeface(fontFamily),
emSize,
Brushes.Black);
return formatted.Width;
}
Включите библиотеки WindowsBase и PresentationCore.
Возможно, это не повторение других, но моей проблемой был также нежелательный объект Graphics. Выслушав вышеописанные разочарования, я просто попытался:
Size proposedSize = new Size(int.MaxValue, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.NoPadding;
Size ressize = TextRenderer.MeasureText(content, cardfont, proposedSize, flags);
(где 'content' - строка для измерения и определения шрифта, в котором она находится)
... и повезло. Я мог бы использовать результат, чтобы установить ширину моего столбца в VSTO.