Qual è il modo più semplice per costruire un FrameworkElement che ha Text Markup grassetto e corsivo?

StackOverflow https://stackoverflow.com/questions/2280924

  •  21-09-2019
  •  | 
  •  

Domanda

C'è un modo più elegante per fare quanto segue?

In sostanza ho bisogno di un modo semplice per programatically costruire un WrapPanel (o altro FrameworkElement) che:

  • avvolge correttamente
  • permette alcune parole di avere grassetto testo
  • permette alcune parole di avere corsivo testo
  • permette altro formattazione , ad esempio il colore di sfondo
  • ideale sarebbe un metodo che converte esempio "This is <b>bold</b> and this is <i>italic</i> text." in un FrameworkElement appropriato così posso esempio aggiungerlo a uno StackPanel e visualizzarlo.

Codice:

using System.Windows;
using System.Windows.Controls;

namespace TestAddTextBlock2343
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            WrapPanel wp = new WrapPanel();

            wp.AddTextBlock("This is a sentence with ");

            {
                TextBlock tb = wp.AddTextBlockAndReturn("bold text");
                tb.FontWeight = FontWeights.Bold;
            }

            wp.AddTextBlock(" and ");

            {
                TextBlock tb = wp.AddTextBlockAndReturn("italic text");
                tb.FontStyle = FontStyles.Italic;
            }

            wp.AddTextBlock(" in it.");
        }
    }

    public static class XamlHelpers
    {
        public static TextBlock AddTextBlockAndReturn(this WrapPanel wp, string text)
        {
            TextBlock tb = new TextBlock();
            tb.Text = text;
            wp.Children.Add(tb);
            return tb;
        }

        public static void AddTextBlock(this WrapPanel wp, string text)
        {
            TextBlock tb = wp.AddTextBlockAndReturn(text);
        }
    }
}
È stato utile?

Soluzione

Edit: ho scoperto in una risposta diversa che il TextBlock ha anche una collezione Inlines a cui si può aggiungere Runs. risposta di Anvaka utilizza ingegnosamente una proprietà allegato come una sorta di convertitore.


Quello che penso soddisferà la vostra situazione è un FlowDocumentScrollViewer e FlowDocument. Descrivo creazione manuale di uno attraverso un IValueConverter un po ' qui .

È probabile che l'utilizzo di funzioni di supporto simili come hai mostrato nel tuo esempio, ma la FlowDocument è già molto simile a HTML e gestirà il confezionamento senza sforzo.

Si aggiunge Paragraphs al FlowDocument, si aggiunge Runs al Paragraph, e ogni Run deriva dal TextElement quindi ha un sacco di le stesse proprietà che fanno TextBlocks.

FlowDocument doc = new FlowDocument();
Paragraph par = new Paragraph();
doc.Blocks.Add( par );

Run r;
r = new Run( "This is " );
par.Inlines.Add( r );

r = new Run( "bold" );
r.FontWeight = FontWeights.Bold;
par.Inlines.Add( r );

r = new Run( " and this is " );
par.Inlines.Add( r );

r = new Run( "italic" );
r.FontStyle = FontStyles.Italic;
par.Inlines.Add( r );

r = new Run( " text." );
par.Inlines.Add( r );

Inoltre, se le stringhe di formattazione stanno andando a rimanere limitato ai tag grassetto / corsivo o qualche altra marcatura estremamente semplice, l'uso di Regex.Split() potrebbe essere il modo più semplice per determinare le Runs separati da una singola stringa. Esso consente di dividere una stringa in più stringhe, ma mantenere i "delimitatori".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top