2012-07-12 17 views
10

Có bất kỳ khả năng để cung cấp một gợi ý WordWrap đến một TextBlock như bạn có thể làm trong HTML với <SHY> (soft hyphen) hoặc <WBR> (word break) hoặc thậm chí phức tạp và duy trì ít hơn zero-width-space &#8203;Wrapping văn bản trong TextBlock

hơn Tại thời điểm này phá vỡ TextBlock Nói cách cũng giống như nó thấy cần thiết, kết thúc với lời kết thúc tốt đẹp như

Stackoverflo
w

những gì tôi muốn là:

Stackover-
dòng

hoặc ít nhất là:

Stackover
dòng

Nếu có đề xuất các cách để đạt được sự cần thiết, vui lòng cho tôi biết.

Trả lời

4

Thiết TextBlock.IsHypenationEnabled true thực sự sẽ làm điều gì đó tương tự như thế, nhưng nếu bạn muốn sử dụng thẻ, bạn có thể sử dụng một phương pháp như thế này:

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

Bằng cách này bạn có thể nói:

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

Điều này sẽ ra:

Just tested

Tuy nhiên, bằng cách sử dụng chỉ IsHyphenated mà không cần thẻ, nó sẽ là:

IsHypehnated Scenario1

Trong khi:

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

chí đầu ra:

Doesn't add <brs> here

Và IsHyphenated mà không cần thẻ:

IsHyphenated Scenario 2

EDIT: On giảm kích thước font chữ, tôi phát hiện ra rằng mã đầu tiên tôi được đăng không thích thêm phá vỡ nơi khoảng trắng xảy ra để người dùng chỉ định phá vỡ.

+0

Cảm ơn bạn! Điều này trông giống như những gì tôi muốn. Phải thử nó trước khi chấp nhận như vậy. –

+0

Hoạt động tốt, chỉ cần thực hiện hai thay đổi nhỏ: 1. textBlock1 được thay thế bằng tham số tb 2. // lấy chỉ mục nơi thẻ xảy ra int i = text.IndexOf (thẻ); nếu (i <0) { trả lại lần lượt + văn bản; } –

+0

Cảm ơn, tôi thực sự nghĩ rằng tôi đã cập nhật điều này ... Để kiểm tra xem thẻ có tồn tại hay không, không cần thiết nếu bạn chỉ sử dụng nó cho các văn bản cần thẻ, nếu bạn muốn tất cả TextBlocks của mình có tính năng, bạn nên thực hiện điều khiển tùy chỉnh và ghi đè thuộc tính thay đổi văn bản ... –

3

Sử dụng TextFormatter kết hợp với tùy chỉnh TextSource để kiểm soát cách văn bản được chia nhỏ và được bao bọc.

Bạn cần phải lấy được một lớp từ TextSource và trong việc thực hiện của bạn phân tích nội dung của bạn/chuỗi và cung cấp gói quy tắc của bạn, ví dụ tìm kiếm thẻ <wbr> của bạn ... khi bạn thấy một thẻ bạn trả về một số TextEndOfLine khác, bạn trả lại TextCharacters.

Một ví dụ có thể giúp trong việc thực hiện một TextSource là ở đây:

Đối với một ví dụ rất tiên tiến nhìn vào "AvalonEdit" mà còn sử dụng nó:

Bạn cũng có thể điều tra GlyphRun nếu bạn không cần định dạng phong phú.

+0

Các ví dụ đó rất tốt! +1 Mặc dù, phải có cách dễ dàng hơn để thực hiện việc này. Có lẽ một textbox gói hiểu một dấu gạch ngang mềm hoặc một cái gì đó như thế. –

+0

Bạn có thể sử dụng RichTextBox và sau đó chỉ cung cấp RTF được định nghĩa phù hợp. –

+0

Trông giống như một ý tưởng hay, phải tìm cách nó hoạt động. –