C# Метка игнорирует пробелы при запросе MeasureString?
Я пытался найти ошибку в приложении типа ленты тикера. Надеюсь, этот фон не слишком долго.
Фон: на ленте тикера должны отображаться символы, начинающиеся справа, а затем прокручиваться влево. Мне нужно использовать метку (или я?) Из-за того, что приложение является формой Windows и нужно, чтобы цвет фона был прозрачным. Были проблемы с использованием разных элементов управления. Размер элемента управления и шрифт неизвестны и должны быть рассчитаны во время выполнения.
Лента тикера имеет основные сценарии, во-первых, начало, где нам нужно PAD слева от отображаемой строки.
Середину, где мы удаляем передние символы и добавляем символы, все еще нужно отобразить.
Конец, который должен нажимать вправо, перемещая последний символ на длину до последнего символа, все влево. Сообщение завершено.
У меня есть 2 функции, которые касаются этого вопроса:
1) Это вычисляет размер отображаемого текста, используя элементы управления и шрифты.
2) В основе приложения лежит функция, которая возвращает отображаемый текст.
Проблема:
Сценарии начала и середины работают отлично, конец не работает, если я дополняю пробелами, но работает, если я использую любой другой видимый символ, такой как "." оно работает.
Функция размера:
Label tstLabel = new Label();
tstLabel.Size = DisplaySize;
tstLabel.Font = new Font(currentMessage.Font, currentMessage.Fonsize);
var g = Graphics.FromHwnd(tstLabel.Handle);
SizeF size = g.MeasureString(text, tstLabel.Font);
return size;
Функция отображения текста:
SizeF spaceSize = getSize(" ");
string text = "";
if(currentCharacter < currentMessage.MessageText.Length )
{
text = currentMessage.MessageText.Substring(0, currentCharacter + 1);
SizeF displayTextSize = getSize(text);
if (displayTextSize.Width <= DisplaySize.Width)
{
int numSpaces = Convert.ToInt32((DisplaySize.Width - displayTextSize.Width) / spaceSize.Width);
text = text.PadLeft(numSpaces + text.Length, ' ');
currentCharacter++;
#endregion
}
else
{
#region Pop char off front
bool keepPadding = true;
do
{
text = text.Substring(1, text.Length - 1);
displayTextSize = getSize(text);
if (displayTextSize.Width <= DisplaySize.Width)
{
keepPadding = false;
}
} while (keepPadding);
currentCharacter++;
#endregion
}
}
else
{
#region Pop char off front and Pad to right
text = currentMessage.MessageText.PadRight(currentCharacter+1,'.');
bool keepPadding = true;
do
{
text = text.Substring(1, text.Length - 1);
SizeF endTextSize = getSize(text);
if (endTextSize.Width <= DisplaySize.Width)
{
if ((DisplaySize.Width - endTextSize.Width) > spaceSize.Width)
{
do
{
text += ".";
endTextSize = getSize(text);
currentCharacter++;
} while ((DisplaySize.Width - endTextSize.Width) > spaceSize.Width);
}
keepPadding = false;
}
} while (keepPadding);
currentCharacter++;
if (checkMessage(text))
nextMessage = true;
}
return text;
Вопрос:
При выполнении функции ниже надписью и пробелами позади текста, почему он возвращает тот же размер?
SizeF size = g.MeasureString (text, tstLabel.Font);
2 ответа
Это устраняет проблему, связанную с MeasureString:
StringFormat strFormat = new StringFormat(StringFormat.GenericTypographic)
{
FormatFlags = StringFormatFlags.MeasureTrailingSpaces
};
size = g.MeasureString(text, tstLabel.Font, tstLabel.Size.Width, strFormat);
Спасибо GSerg!
SizeF size = g.MeasureString(text, tstLabel.Font, tstLabel.ClientSize,
new StringFormat(StringFormatFlags.MeasureTrailingSpaces));
Однако, если вы хотите использовать тот же рендеринг, что и в WinForms, используйте TextRenderer.MeasureText
а также TextRenderer.DrawText
вместо. Начиная с.NET 2.0 Graphics.MeasureString
а также DrawString
используются только когда UseCompatibleTextRendering
свойство это правда.