Silverlight: как предсказать размер строки? - PullRequest
8 голосов
/ 07 ноября 2010

Я сталкиваюсь с большой проблемой в Silverlight, как с макетом. В основном, я не могу найти способ предсказать размер, занимаемый строками, до того, как они будут нарисованы. На iPhone у нас есть несколько очень простых методов, которые позволяют нам определить размер строки на экране, основываясь на размере шрифта, опции переноса слов и доступной ширине и / или высоте. Но с Silverlight я не могу найти способ добиться стабильных результатов в своем приложении.

В настоящее время я использую ActuelHeight и ActualWidth экземпляра TextBlock, но он дает мне случайные результаты. Например, я использую следующий код ...

TextBlock proto = new TextBlock();

proto.Width = 456;
proto.TextWrapping = TextWrapping.Wrap;
proto.Text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
double h = proto.ActualHeight;

... h установлен на 66 пикселей! Как вы можете догадаться, такой длинный текст не может поместиться в прямоугольнике шириной 456 пикселей и высотой 66 пикселей. И это подтверждается, когда я добавляю текстовый блок внутри холста, устанавливаю его размер {456; 66} и проверяю приложение: текст вообще не помещается в текстовый блок!

Может ли кто-нибудь объяснить мне, в чем заключается проблема, и указать на непротиворечивый (и надежный) способ измерения размеров строк?

Спасибо заранее,

Эрик.

Ответы [ 5 ]

12 голосов
/ 07 ноября 2010

Вы можете попросить TextBlock измерить себя (пока он не отображается), вызвав его метод Measure:

textBlock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var width = textBlock.DesiredSize.Width;
var height = textBlock.DesiredSize.Height;

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

3 голосов
/ 07 ноября 2010

Где возможно, попытайтесь создать дизайн, в котором вам не нужно знать физический размер текстового блока. Используйте прокрутку и динамическое изменение размера, чтобы избежать необходимости знать это.

Однако, если вы действительно должны это знать, вы можете попробовать этот трюк с рабочего стола (где было невозможно использовать MeasureText - извините, не поддерживается в Silverlight) Добавьте текстовый блок в пользовательский интерфейс, но вне видимой области или за другим элементом управления. Вы можете получить фактический размер рендеринга.

1 голос
/ 08 ноября 2010

Спасибо за вашу помощь, ребята, на самом деле мой первый метод работал! Но я забыл установить fontSize перед извлечением ActualHeight - и он был автоматически установлен родителем после добавления в визуальное дерево! Таким образом, 66 пикселей были фактически правильной высотой моего текстового блока с небольшим размером шрифта, используемым по умолчанию текстовым блоком. После добавления в визуальное дерево размер шрифта текстового блока стал намного больше, что привело к клипированию.

Еще раз спасибо за помощь!

1 голос
/ 07 ноября 2010

TextBlock не изменит свой размер, пока он не отобразится ...

В остальном я думаю, что это вопрос дизайна. В среде XAML вам не нужно знать / устанавливать размеры пикселей очень часто.

0 голосов
/ 05 мая 2012

Мое решение состоит в том, чтобы использовать 3 или более TextBlocks:

string[] dataSeparator = new string[] { "\n" };
string[] data;
data = longString.Split(dataSeparator, StringSplitOptions.None);
TB1.Text = string.Empty;
TB2.Text = string.Empty;
TB3.Text = string.Empty;
int length = data.Length / 3;
for (int i = 0; i < length; i++)
{
    TB1.Text += data[i] + "\n";
}
for (int i = length; i < length * 2; i++)
{
    TB2.Text += data[i] + "\n";
}
for (int i = length * 2; i < data.Length; i++)
{
    TB3.Text += data[i] + "\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...