WPF: estrae il testo “incartato” da una casella di testo

C’è un modo in WPF per ottenere il testo formattato mentre viene visualizzato nella casella di testo quando TextWrapping = “Wrap”?

 

Ho provato a utilizzare la class TextFormatter, ma mi consente di disegnare il testo in un contesto di disegno in cui ho solo bisogno del testo con interruzione di riga inclusa.

Ecco come ottenere il testo completo con interruzioni di riga apparenti.

Nota:

  • Includi le seguenti classi da Esempio di formattazione avanzata del testo nel tuo progetto:
    • CustomTextSource
    • FontRendering
    • GenericTextProperties
  • Esistono alcune limitazioni menzionate nella class CustomTextSource. Tuttavia, ritengo che i tuoi requisiti non siano influenzati da tali limiti.
  • Questi sono solo esempi. Potresti voler modificare il codice secondo le tue esigenze.
  • Il codice usa ancora un hack (anche se decente) – InputTextBox.ViewportWidth . Potresti voler verificare se l’output finale è esattamente come desiderato.

Vedi: Formattazione avanzata del testo e Esempio di formattazione avanzata del testo

Codice di esempio
XAML:

        

codebehind:

 private void CopyButton_Click(object sender, RoutedEventArgs e) { List 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 GetTextAsStringList() { List stringList = new List(); 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; } 

Per questo devi scrivere la tua logica facendo uso dell’API di misurazione del testo.

PASSO 1: Bresk il testo della casella di testo in a parole.

PASSO 2: quindi misura ogni larghezza di parola e combinale finché la larghezza della linea è inferiore alla larghezza della casella di testo.

Consulta questo post che spiega il processo di misurazione del testo. (Social.msdn.microsoft.com/forums/en-US/wpf/thread/…)

Vedere la risposta di Ian Griffiths a questa domanda: Ottieni testo visualizzato da TextBlock

Ottiene il testo visualizzato (come viene presentato sullo schermo) da un TextBlock ma penso che dovresti essere in grado di usarlo anche per un TextBox

Se tutto ciò che si desidera è il testo della casella di testo (testo completo e non solo la parte visibile), per essere visualizzato come testo (con interruzioni di riga apparenti) nella stessa finestra in un blocco di testo, un attacco rapido potrebbe essere:

 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; 

Se è necessario in qualche altro posto, puoi portare i valori in quel posto e usarli sul blocco di testo lì.

Se è necessario il testo completo (con interruzioni di riga apparenti) come elenco di stringhe (ad es. List ) in cui ogni elemento rappresenta la linea apparente, sarà necessaria una soluzione complessa.
Inoltre, se è necessaria solo la parte visibile del testo visualizzata nella casella di testo, è necessario eseguire nuovamente una soluzione complessa.