Я использую WPF. В моем приложении есть текстовые блоки с изменяемым текстом внутри. Каждый из них имеет ширину 200 и высоту 150. Проблема в том, что у меня есть 7 текстовых блоков, подобных тем, и я хочу, чтобы они имели одинаковый размер шрифта. Текст должен быть авторизован. Я знаю, что может их автоподтвердить. Но когда у кого есть предложение внутри, а другое только два слова, размер шрифта настолько разный ... Мне нужно пересчитать размер асинхронно (например, создав какое-то событие, например OnTextChange). Текст внутри блоков изменяется динамически. Как написать функцию? Я хочу передать 3 параметра: текст, шрифт (шрифт семьи + стиль шрифта) и размер текстового блока, а также вернуть размер шрифта.Подсчет размера шрифта асинхронно
ответ
Лучший способ определить размер шрифта - это измерить текст любого произвольного размера, а затем умножить его на отношение его размера к размеру области.
Например, если вы измеряете текст, и он составляет половину от размера контейнера, в котором он находится, вы можете умножить его на 2, и он должен заполнить контейнер. Вы хотите выбрать минимальное соотношение ширины и высоты для использования.
В WPF класс FormattedText выполняет измерение текста.
public double GetFontSize(string text, Size availableSize, Typeface typeFace)
{
FormattedText formtxt = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeFace, 10, Brushes.Black);
double ratio = Math.Min(availableSize.Width/formtxt.Width, availableSize.Height/formtxt.Height);
return 10 * ratio;
}
Вы должны использовать эту функцию каждый раз, когда вы изменяете текст вашего TextBlocks, например, так:
txtBlock.FontSize = GetFontSize(txt.Text, new Size(txt.ActualWidth, txt.ActualHeight), new Typeface(txt.FontFamily, txt.FontStyle, txt.FontWeight, txt.FontStretch));
Edit:
Для целей практичности, вы можете быть чтобы текст мог центрировать по вертикали в этом предопределенном ограничивающем прямоугольнике. Хороший способ сделать это - обернуть свой TextBlock внутри другого объекта, такого как элемент Border. Таким образом вы можете указать, что TextBlock выровнен по центру границы, и он может автоматически настраиваться в соответствии с его содержимым.
Ok. Работает отлично. Но у меня другая проблема. Я написал 2 метода в MainWindow.cs:
private void fitFontSize()
{
propertiesList.Clear();
TextUtils.FontProperty fontProps = new TextUtils.FontProperty();
foreach (TextBlock tb in findVisualChildren<TextBlock>(statusOptionsGrid))
{
fontProps.Text = tb.Text;
fontProps.Size = new Size(tb.ActualWidth, tb.ActualHeight);
fontProps.FontFamily = tb.FontFamily;
fontProps.FontStyle = tb.FontStyle;
fontProps.FontWeight = tb.FontWeight;
fontProps.FontStretch = tb.FontStretch;
propertiesList.Add(fontProps);
}
MessageBox.Show(TextUtils.recalculateFontSize(propertiesList) + "");
}
public IEnumerable<T> findVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in findVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
После этого я создал новый класс для обработки текста. Вот код:
public class TextUtils
{
public class FontProperty
{
public FontFamily FontFamily { get; set; }
public FontStyle FontStyle { get; set; }
public FontWeight FontWeight { get; set; }
public FontStretch FontStretch { get; set; }
public string Text { get; set; }
public Size Size { get; set; }
public Typeface getTypeFace()
{
return new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
}
}
public static double recalculateFontSize(List<FontProperty> propertiesList)
{
List<double> fontSizes = new List<double>();
foreach (FontProperty fp in propertiesList)
{
fontSizes.Add(getFontSizeForControl(fp));
}
return fontSizes.Min<double>();
}
private static double getFontSizeForControl(FontProperty fp)
{
string text = fp.Text;
Size availableSize = fp.Size;
Typeface typeFace = fp.getTypeFace();
FormattedText formtxt = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeFace, 10, Brushes.Black);
double ratio = Math.Min(availableSize.Width/formtxt.Width, availableSize.Height/formtxt.Height);
return 10 * ratio;
}
}
Код выглядит плохо, но я исправлю это позже ...
Ok. Теперь я хочу создать новый таймер, который проверяет размер шрифта каждую секунду. Когда я пытаюсь использовать метод fitFontSize() в нем, я получаю сообщение msg: «Вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток». Как это сделать, чтобы избежать подобных проблем? Я попробовал (просто попробую) создать новый поток, вызывающий этот метод. Но есть та же проблема с методом findVisualChildren <>() - он вызывается в fitFontSize(). У меня нет никаких идей, как решить мою проблему ...
- 1. Неверный подсчет размера шрифта
- 2. Расчет размера шрифта
- 3. getOrgChart изменение размера шрифта
- 4. Ошибка размера шрифта
- 5. размера шрифта на язык
- 6. Изменение размера шрифта этикеток
- 7. iphone - вычисление размера шрифта
- 8. Изменение размера шрифта tabbaritem
- 9. Изменение размера шрифта pdfptable
- 10. Меню размера шрифта TinyMCE
- 11. Изменение размера шрифта valueBoxes
- 12. Изменение размера шрифта
- 13. Пользовательские настройки размера шрифта
- 14. Изменение размера шрифта метки
- 15. увеличение размера шрифта непрерывно
- 16. изменение размера шрифта автоматически
- 17. Изменение размера шрифта HTML
- 18. Android размера шрифта кнопки
- 19. SVG размера шрифта относительно размера Viewbox
- 20. Изменение размера и размера шрифта listview
- 21. Изменение размера шрифта при изменении размера div
- 22. Автоматическая настройка размера шрифта при изменении размера
- 23. Изменение размера шрифта при изменении размера окна
- 24. Изменение размера и стиля шрифта
- 25. Настройка шрифта и размера изображения
- 26. ошибка размера шрифта с CGContextShowTextAtPoint
- 27. Изменение размера шрифта в AlertDialog
- 28. изменение размера шрифта после перезагрузки
- 29. Игнорирование установки размера шрифта ICS
- 30. CSS: Автоматическое обновление размера шрифта