2012-07-12 16 views
10

Czy są jakieś możliwości zapewnienia sugestię wordWrap do textblock jak można zrobić w HTML z <SHY> (soft hyphen) lub <WBR> (word break) lub jeszcze bardziej skomplikowany i mniej utrzymaniu zero-width-space &#8203;owijania w TextBlock

w momencie przerwy textblock słowa tak jak to widzi konieczność, kończy się słowem zawija jak

Stackoverflo
w

co chcę jest:

Stackover-
przepływu

lub co najmniej:

Stackover
przepływu

Jeśli istnieją zalecane sposoby osiągnięcia potrzebnych, proszę dać mi znać.

Odpowiedz

4

Ustawianie TextBlock.IsHypenationEnabled true faktycznie zrobić coś podobnego do tego, ale jeśli chcesz używać tagów, można użyć metody takie jak to:

/// <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; 
    } 

ten sposób możesz teraz powiedzieć:

textBlock1.Text = WordWrap("StackOver<br>Flow For<br>Ever", textBlock1, "<br>"); 

To wyświetli:

Just tested

Jednak użycie IsHyphenated tylko bez znaczników, to będzie:

IsHypehnated Scenario1

Podczas:

textBlock1.Text = WordWrap("StackOver<br>Flow In<br> U", textBlock1, "<br>"); 

wyjście wola:

Doesn't add <brs> here

I IsHyphenated bez tags:

IsHyphenated Scenario 2

EDIT: Na zmniejszenie rozmiaru czcionki, odkryłem, że pierwszy kod napisałem nie wolą dodanie przerwy gdzie spacje występujące na określony przez użytkownika przerw.

+0

Dziękujemy! Wygląda dokładnie tak, jak chcę. Zanim ją zaakceptujesz, musisz to wypróbować. –

+0

Działa dobrze, wystarczyło wprowadzić dwie drobne zmiany: 1. tekstBlock1 zostaje zastąpiony przez parametr tb 2. // pobierz indeks, w którym wystąpił znacznik int i = text.IndexOf (tag); if (i <0) { return ret + text; } –

+0

Dzięki, naprawdę myślałem, że to zaktualizowałem ... Jeśli chodzi o sprawdzanie, czy tag istnieje, nie jest konieczne, jeśli używasz go tylko do tekstów, które wymagają znacznika, również jeśli chcesz, aby wszystkie twoje TextBlocky miały to należy wykonać niestandardową kontrolę i zastąpić właściwość zmiany tekstu ... –

3

Użyj TextFormatter w połączeniu z niestandardowym TextSource, aby kontrolować sposób podziału i zawijania tekstu.

Trzeba czerpać klasę z TextSource i implementacji analizować zawartość/string i podać swoje zasady owijania, na przykład poszukaj znacznika <wbr> ... gdy zobaczysz znacznik, zwrócisz TextEndOfLine w przeciwnym razie zwrócisz TextCharacters.

Przykładem, który może pomóc w realizacji TextSource jest tutaj:

Przez bardzo zaawansowany przykład spojrzeć na "AvalonEdit", który również używa go:

Możesz również zbadać, czy nie potrzebujesz bogatego formatowania GlyphRun.

+0

Te przykłady są bardzo dobre! +1 Chociaż musi być łatwiejszy sposób na zrobienie tego. Być może opakowanie tekstowe, które rozumie miękki łącznik lub coś w tym stylu. –

+0

Można użyć RichTextBox, a następnie po prostu dostarczyć odpowiednio zdefiniowane RTF. –

+0

Wygląda na to, że jest to dobry pomysł, musisz dowiedzieć się, jak to działa. –