Проблема изменения размера метки Windows Forms - PullRequest
2 голосов
/ 25 ноября 2011

У меня есть приложение winform, на котором я размещаю ярлык. Я изменяю текст метки динамически из фонового потока. Изменение текста запускает событие, которое должно изменить размер метки. Все работает нормально, за исключением того, что длина строки, которую я измеряю, неверна, и, следовательно, размер метки клиента неверен.

protected void progressInfo_TextChanged(object sender, EventArgs e)
{
    // Auto size label to fit the text
    // ... create a Graphics object for the label
    Graphics g_progressInfo = this.progressInfo.CreateGraphics();

    // ----------------
    // Set up string.
    string text1 = "Reading data from input data file ... inputData";
    Font stringFont = new System.Drawing.Font("Verdana", 8,
        System.Drawing.FontStyle.Regular);

    Size textSize = TextRenderer.MeasureText(text1, stringFont);
    TextRenderer.DrawText(g_progressInfo, text1, stringFont,
        new Rectangle(new Point(10, 10), textSize), Color.Red);

    System.Diagnostics.Debug.WriteLine("textSize = " + (textSize).ToString());
    // ----------------

    // Set the TextRenderingHint property.
    g_progressInfo.TextRenderingHint =
        System.Drawing.Text.TextRenderingHint.AntiAlias;

    // ... get the Size needed to accommodate the formatted text
    Size preferredSize_progressInfo = g_progressInfo.MeasureString(
        this.progressInfo.Text, this.progressInfo.Font).ToSize();
    System.Diagnostics.Debug.WriteLine("preferredSize_progressInfo = " +
        (preferredSize_progressInfo).ToString());
    /*
        g_progressInfo.MeasureString above calculates the size of the string as floting
        point numbers that get truncated by .ToSize().
        ... pad the text by 1 pixel, and resize the label
     */
    System.Diagnostics.Debug.WriteLine("this.progressInfo.ClientSize = " +
        (this.progressInfo.ClientSize).ToString());
    this.progressInfo.ClientSize = new Size(
        preferredSize_progressInfo.Width + 10, preferredSize_progressInfo.Height + 1);
    System.Diagnostics.Debug.WriteLine("this.progressInfo.ClientSize = " +
        (this.progressInfo.ClientSize).ToString());
    // ... clean up the Graphics object
    g_progressInfo.Dispose();
}

Вот результат отладки:

Result from TextRenderer           ---> textSize = {Width=270, Height=13}
Size calculated by MeasureString() ---> preferredSize_progressInfo = {Width=260, Height=14}
Initial label client size          ---> progressInfo.ClientSize = {Width=100, Height=23}
Resized client size based on MeasureString ---> this.progressInfo.ClientSize = {Width=270, Height=15}

Проблема в том, что рассчитанная ширина строки отличается на 10 пикселей. Как оказалось, ширина, вычисленная TextRenderer, width = 270, является правильной, а ширина, вычисленная MeasureString, width = 260, неверной, поскольку она усекает отображение входной строки до: «Чтение данных из файла входных данных. .. вход ". Я также попытался измерить ширину строки с помощью MeasureCharacterRanges (), и этот подход дает результат, аналогичный результату, полученному с помощью метода MeasureString. Кажется, что размер, рассчитанный TextRenderer, правильно отображает текст.

Да, я понимаю, что в этом случае я должен просто использовать TextRenderer, но может ли кто-нибудь объяснить мне источник такого огромного расхождения в ширине строки, рассчитанной различными методами? Любая помощь или руководство будет принята с благодарностью. Спасибо.

1 Ответ

1 голос
/ 25 ноября 2011

Я действительно нашел ответ на это. Это было в предыдущем посте на stackoverflow под названием TextRenderer.MeasureText и Graphics.MeasureString не соответствуют размеру , и Свен ответил следующим образом:

TextRenderer использует GDI для визуализации текста, тогда как Graphics использует GDI +. Оба используют немного другой метод для разметки текста, поэтому размеры отличаются.

Какой из них использовать, зависит от того, что в итоге будет использовано для рисования текста. Если вы рисуете его с помощью GDI + Graphics.DrawString, измерьте с помощью Graphics.MeasureString. Если вы рисуете с использованием GDI TextRenderer.DrawText, измерьте с помощью TextRenderer.MeasureText.

Если текст будет отображаться внутри элемента управления Windows Forms, он использует TextRenderer, если для UseCompatibleTextRendering задано значение false (по умолчанию).

Я хочу добавить, что настройка UseCompatibleTextRendering = true на моем элементе управления улучшила ситуацию, но не полностью разрешила ее. На этот раз входная строка была обрезана в «Чтение данных из файла входных данных ... inputDa». Поэтому может показаться, что использование TextRenderer - это путь к элементам управления Winform.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...