Перенос текста в TextBlock
есть ли возможности предоставить предложение wordwrap текстовому блоку
как можно сделать в HTML <SHY> (soft hyphen)
или <WBR> (word break)
или
еще более сложным и менее ремонтопригодным zero-width-space
В данный момент Textblock разбивает слова так же, как он видит необходимость, заканчивая слово обертывания как
Stackoverflo
w
чего я хочу, так это:
Stackover-
поток
или на минимум:
Stackover
поток
Если порекомендуйте пути достигнуть необходимого, то пожалуйста дайте мне знать.
2 ответов
задание TextBlock.IsHypenationEnabled
to true фактически сделает что-то подобное этому, но если вы хотите использовать теги, вы можете использовать такой метод:
/// <summary>
/// Adds break to a TextBlock according to a specified tag
/// </summary>
/// <param name="text">The text containing the tags to break up</param>
/// <param name="tb">The TextBlock we are assigning this text to</param>
/// <param name="tag">The tag, eg <br> to use in adding breaks</param>
/// <returns></returns>
public string WordWrap(string text, TextBlock tb, string tag)
{
//get the amount of text that can fit into the textblock
int len = (int)Math.Round((2 * tb.ActualWidth / tb.FontSize));
string original = text.Replace(tag, "");
string ret = "";
while (original.Length > len)
{
//get index where tag occurred
int i = text.IndexOf(tag);
//get index where whitespace occurred
int j = original.IndexOf(" ");
//does tag occur earlier than whitespace, then let's use that index instead!
if (j > i && j < len)
i = j;
//if we usde index of whitespace, there is no need to hyphenate
ret += (i == j) ? original.Substring(0, i) + "\n" : original.Substring(0, i) + "-\n";
//if we used index of whitespace, then let's remove the whitespace
original = (i == j) ? original.Substring(i + 1) : original.Substring(i);
text = text.Substring(i + tag.Length);
}
return ret + original;
}
таким образом, теперь вы можете сказать:
textBlock1.Text = WordWrap("StackOver<br>Flow For<br>Ever", textBlock1, "<br>");
это выведет:
однако, используя только IsHyphenated без тегов, это будет:
в то время как:
textBlock1.Text = WordWrap("StackOver<br>Flow In<br> U", textBlock1, "<br>");
вывод:
И IsHyphenated без тегов:
EDIT: При уменьшении размера шрифта я обнаружил, что первый код, который я опубликовал, не предпочитаю добавление разрывов, в которых пробелы встречаются с указанными пользователем разрывами.
использовать TextFormatter
в сочетании с настраиваемой TextSource
для управления тем, как текст разбивается и упаковывается.
вам нужно вывести класс из TextSource и в вашей реализации проанализировать содержимое / строку и предоставить свои правила обертывания, например, поиск тега TextEndOfLine
иначе вы возвращаете TextCharacters
.
пример что может помочь в реализации TextSource
здесь:
для очень продвинутого примера посмотрите на "AvalonEdit" , который также использует его:
вы также можете исследовать GlyphRun
если вам не нужны богатые форматирование.