Измерение текста в WPF - PullRequest
19 голосов
/ 11 марта 2009

Каков наиболее эффективный способ измерения большого количества коротких строк с помощью WPF? В частности, я хотел бы определить высоту отображения каждой строки, учитывая единообразное форматирование (тот же шрифт, размер, вес и т. Д.) И максимальную ширину, которую может занимать строка?

Ответы [ 4 ]

13 голосов
/ 11 марта 2009

Самым низкоуровневым методом (и, следовательно, дающим наибольшую возможность для творческой оптимизации) является использование GlyphRuns.

Это не очень хорошо задокументировано, но я написал небольшой пример здесь:

http://smellegantcode.wordpress.com/2008/07/03/glyphrun-and-so-forth/

В этом примере длина строки рассматривается как необходимый шаг перед ее обработкой.

6 голосов
/ 30 ноября 2012

В WPF:

Не забудьте вызвать Measure () для TextBlock перед чтением свойства DesiredSize.

Если TextBlock был создан на лету и еще не отображен, сначала необходимо вызвать Measure (), например:

MyTextBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

return new Size(MyTextBlock.DesiredSize.Width, MyTextBlock.DesiredSize.Height);

В Silverlight:

Не нужно измерять.

return new Size(TextBlock.ActualWidth, TextBlock.ActualHeight);

Полный код выглядит так:

public Size MeasureString(string s) {

    if (string.IsNullOrEmpty(s)) {
        return new Size(0, 0);
    }

    var TextBlock = new TextBlock() {
        Text = s
    };

#if SILVERLIGHT
    return new Size(TextBlock.ActualWidth, TextBlock.ActualHeight);
#else
    TextBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

    return new Size(TextBlock.DesiredSize.Width, TextBlock.DesiredSize.Height);
#endif
}
6 голосов
/ 03 марта 2012

Это очень просто и сделано классом FormattedText! Попробуй.

3 голосов
/ 11 марта 2009

Вы можете использовать свойство DesiredSize на визуализированном TextBox, чтобы получить высоту и ширину

using System.Windows.Threading;

...

Double TextWidth = 0;
Double TextHeight = 0;
...

MyTextBox.Text = "Words to measure size of";
this.Dispatcher.BeginInvoke(
    DispatcherPriority.Background,
    new DispatcherOperationCallback(delegate(Object state) {
        var size = MyTextBox.DesiredSize;
        this.TextWidth = size.Width;
        this.TextHeight = size.Height;
        return null; 
    }
) , null);

Если у вас большое количество строк, может быть быстрее выполнить предварительный расчет высоты и ширины каждой индивидуальной буквы и символа в данном шрифте, а затем выполнить вычисление на основе строковых символов. Это не может быть на 100% точным из-за кернинга и т. Д.

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