2011-04-19 45 views
5

Có cách nào trong WPF để văn bản được định dạng khi văn bản hiển thị trên hộp văn bản khi TextWrapping = "Wrap" không?WPF: Lấy văn bản "gói" ra khỏi hộp văn bản

<TextBox Width="200" 
      TextWrapping="Wrap"     
      VerticalScrollBarVisibility="Auto" 
      HorizontalScrollBarVisibility="Auto" /> 

Tôi đã cố gắng sử dụng lớp TextFormatter, nhưng nó cho phép tôi vẽ văn bản vào ngữ cảnh vẽ nơi tôi chỉ cần văn bản có ngắt dòng được bao gồm.

+0

tôi xin lỗi nhưng không thể hiểu được vấn đề stat ement. Có phải bạn muốn sao chép văn bản từ hộp văn bản đó và trong khi dán ở một nơi khác muốn bảo vệ các vị trí được bao bọc? – publicgk

+0

Văn bản hoặc dưới dạng hình ảnh/hình ảnh? –

+0

@publicgk, trường hợp chính xác của tôi là chuyển văn bản sang báo cáo đang hoạt động trong khi vẫn giữ vị trí được bọc để tôi có cùng một gói được hiển thị trên màn hình. Vì vậy, tôi cần nó như là văn bản. – Fbeauche

Trả lời

3

Dưới đây là cách để có được văn bản hoàn chỉnh với ngắt dòng rõ ràng.

Lưu ý:

  • Bao gồm các lớp sau đây từ Advanced Text Formatting Example trong dự án của bạn:
    • CustomTextSource
    • FontRendering
    • GenericTextProperties
  • Có một số hạn chế mà được đề cập trong CustomTextSource lớp học. Tuy nhiên, tôi tin rằng yêu cầu của bạn không bị ảnh hưởng bởi những hạn chế đó.
  • Đây chỉ là ví dụ. Bạn có thể muốn sửa đổi mã theo nhu cầu của bạn.
  • Mã vẫn sử dụng một hack (mặc dù là một tài khoản phong nha) - InputTextBox.ViewportWidth. Bạn có thể muốn kiểm tra xem kết quả cuối cùng là chính xác là như mong muốn.

Xem: Advanced Text FormattingAdvanced Text Formatting Example

Mã mẫu
XAML:

<Window x:Class="TextFormatterForWrappedText.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TextBox Width="200" 
      x:Name="InputTextBox" 
      TextWrapping="Wrap" 
      VerticalScrollBarVisibility="Auto" 
      HorizontalScrollBarVisibility="Auto" Margin="23,12,280,241" /> 
     <TextBox x:Name="FormattedDisplayTextBox" Height="172" 
       HorizontalAlignment="Left" VerticalAlignment="Top" 
       Margin="23,105,0,0" Width="438" AcceptsReturn="True" 
       TextWrapping="Wrap" /> 
     <Button HorizontalAlignment="Left" VerticalAlignment="Top" 
       Margin="257,12,0,0" Height="23" Content="Copy" 
       Name="CopyButton" Width="129" Click="CopyButton_Click" /> 
    </Grid> 
</Window> 

codebehind:

private void CopyButton_Click(object sender, RoutedEventArgs e) 
{ 
    List<string> stringList = GetTextAsStringList(); 
    StringBuilder sb = new StringBuilder(); 
    foreach (string s in stringList) 
    { 
     sb.Append(s); 
     sb.Append("\r\n"); 
    } 

    Clipboard.SetData(System.Windows.DataFormats.Text, sb.ToString()); 

    FormattedDisplayTextBox.Clear(); 
    FormattedDisplayTextBox.Text = sb.ToString(); 
} 

private List<string> GetTextAsStringList() 
{ 
    List<string> stringList = new List<string>(); 
    int pos = 0; 
    string inputText = InputTextBox.Text; 

    CustomTextSource store = new CustomTextSource(); 
    store.Text = inputText; 
    store.FontRendering = new FontRendering(InputTextBox.FontSize, 
              InputTextBox.TextAlignment, 
              null, 
              InputTextBox.Foreground, 
              new Typeface(InputTextBox.FontFamily, 
               InputTextBox.FontStyle, 
               InputTextBox.FontWeight, 
               InputTextBox.FontStretch)); 

    using (TextFormatter formatter = TextFormatter.Create()) 
    { 
     while (pos < store.Text.Length) 
     { 
      using (TextLine line = formatter.FormatLine(store, 
            pos, 
            InputTextBox.ViewportWidth, 
            new GenericTextParagraphProperties(
             store.FontRendering), 
            null)) 
      { 
       stringList.Add(inputText.Substring(pos, line.Length - 1)); 
       pos += line.Length; 
      } 
     } 
    } 

    return stringList; 
} 
+0

Woa, cảm ơn rất nhiều công trình perferct :). Tôi đã phải điều chỉnh một chút mã vì nó đã cắt ngắn char cuối cùng của mỗi dòng trừ dòng cuối cùng. – Fbeauche

+1

Bạn có thể chỉnh sửa câu trả lời với bản sửa lỗi bạn đã thực hiện không? –

+0

Các liên kết đến "Ví dụ về định dạng văn bản nâng cao" bị hỏng. – Victor

1

Để làm điều đó, bạn phải viết logic của riêng mình bằng cách sử dụng API đo lường văn bản.

BƯỚC 1: Khiến văn bản hộp văn bản thành từ.

BƯỚC 2: Sau đó, đo từng chiều rộng từ và kết hợp chúng cho đến khi độ rộng của đường nhỏ hơn chiều rộng của hộp văn bản.

Tham khảo bài đăng này giải thích về quy trình đo văn bản. (Social.msdn.microsoft.com/forums/en-US/wpf/thread/...)

+0

Đó không phải là vấn đề, anh/cô ấy muốn nhận được văn bản ở định dạng mà TextBlock tự động áp đặt trên văn bản. –

+0

@ H.B. Của tôi xấu! .. Tôi nghĩ rằng ông đang tìm cách để xử lý văn bản tràn mà không sử dụng TextBox. –

+0

@ H.B. BTW, Sẽ làm cho hộp văn bản chỉ đọc sẽ là một lựa chọn hợp lệ trong trường hợp này? –

1

Xem câu trả lời bằng cách Ian Griffiths cho câu hỏi này: Get Displayed Text from TextBlock

Nó được văn bản hiển thị (như nó được trình bày trên màn hình) từ một số TextBlock nhưng tôi nghĩ bạn có thể sử dụng nó cho một số TextBox cũng như

+0

Bài đăng tốt ở đó, nhưng tôi dường như không làm cho nó hoạt động tốt với hộp văn bản. Tôi đã có thể nhận được văn bản hiển thị với một số tinh chỉnh, nhưng tôi không thể lấy toàn bộ văn bản trong hộp văn bản ... – Fbeauche

1

Nếu tất cả bạn muốn là văn bản của hộp văn bản (văn bản hoàn chỉnh và không chỉ phần hiển thị), hiển thị dưới dạng văn bản (có ngắt dòng rõ ràng) trên cùng một cửa sổ trong một số khối văn bản, một hack nhanh có thể là:

FormattedText ft = new FormattedText(textBox1.Text, 
    System.Globalization.CultureInfo.CurrentCulture, 
    textBox1.FlowDirection, 
    new Typeface(textBox1.FontFamily, 
     textBox1.FontStyle, 
     textBox1.FontWeight, 
     textBox1.FontStretch), 
    textBox1.FontSize, 
    textBox1.Foreground); 
ft.TextAlignment = textBox1.TextAlignment; 
ft.Trimming = TextTrimming.None; 

ft.MaxTextWidth = textBox1.ViewportWidth; 

textBlock1.Width = textBox1.ViewportWidth; 
textBlock1.Height = ft.Height; 

textBlock1.TextAlignment = textBox1.TextAlignment; 
textBlock1.TextWrapping = textBox1.TextWrapping; 
textBlock1.Text = textBox1.Text; 

Nếu được yêu cầu ở một số nơi khác, bạn có thể mang giá trị đến địa điểm đó và sử dụng chúng trên khối chữ đó.

Nếu bạn cần văn bản hoàn chỉnh (có ngắt dòng rõ ràng) dưới dạng danh sách chuỗi (ví dụ: List<string>) trong đó mỗi mục đại diện cho dòng rõ ràng, bạn sẽ cần một giải pháp phức tạp.
Ngoài ra, nếu bạn chỉ cần phần hiển thị của văn bản như được hiển thị trong hộp văn bản, một lần nữa một số giải pháp phức tạp là bắt buộc.

+0

Tôi cần văn bản hoàn chỉnh và không sử dụng nó để hiển thị nó trên màn hình: ( – Fbeauche

Các vấn đề liên quan