Zeilenumbruch im Zeichenfolgenattribut

283

Wie kann ich dem Text einen Zeilenumbruch hinzufügen, wenn er als Attribut festgelegt wird?

<TextBlock Text="Stuff on line1 \n Stuff on line2" />

Es ist für meine spezielle Situation keine Option, es in das explodierte Format aufzuteilen. Was ich brauche, ist eine Möglichkeit, Folgendes zu emulieren:

<TextBlock>
  <TextBlock.Text>
    Stuff on line1 <LineBreak/>
    Stuff on line2
  </TextBlock.Text>
<TextBlock/>
MojoFilter
quelle

Antworten:

553
<TextBlock Text="Stuff on line1&#x0a;Stuff on line 2"/>

Sie können einen beliebigen hexadezimal codierten Wert verwenden, um ein Literal darzustellen. In diesem Fall habe ich den Zeilenvorschub verwendet (Zeichen 10). Wenn Sie "klassisch" machen möchten, vbCrLfkönnen Sie verwenden&#x0d;&#x0a;

Beachten Sie übrigens die Syntax: Es ist das kaufmännische Und, ein Pfund, der Buchstabe x , dann der Hex-Wert des gewünschten Zeichens und schließlich ein Semikolon.

AUCH: Der Vollständigkeit halber können Sie an einen Text binden, in den bereits die Zeilenvorschübe eingebettet sind, wie eine Konstante in Ihrem Code oder eine zur Laufzeit erstellte Variable.

Bob King
quelle
14
Anscheinend funktioniert dies nicht in <TextBlock.Text> </ TextBlock.Text> -Tags.
Kabel
45
Bis heute habe ich 34 positive Stimmen zu dieser Antwort, und ich musste immer noch zurückkommen und nachsehen, weil die Syntax so archaisch ist.
Bob King
3
Absolut. Ich habe dieses Lesezeichen. Ich muss die ganze Zeit kommen und es überprüfen.
MojoFilter
4
'Archaic' ==> 'Arcane' :-)
Will Dean
5
Funktioniert sogar innerhalb eines Bindungsparameters, wenn ein Backslash wie folgt hinzugefügt wird: ConverterParameter = 'Test \ & # x0a; Text'
Sven
72

Möglicherweise können Sie das Attribut xml: space = "bewahren" verwenden, um Leerzeichen in der Quell-XAML beizubehalten

<TextBlock xml:space="preserve">
Stuff on line 1
Stuff on line 2
</TextBlock>
scrat789
quelle
8
Sie können auch xml: space = "bewahren" entfernen und <LineBreak /> zwischen den Zeilen
hinzufügen
5
Es sollte beachtet werden (einige Jahre später), dass xml:space="preserve"auch die Einrückungsräume erhalten bleiben, die normalerweise in XAML vorhanden sind. Daher <LineBreak />scheint ein expliziter wie oben vorgeschlagen eine sauberere Lösung zu sein.
Zeus
Vielen Dank! Diese Lösung passte sehr gut zu meinem XAML-basierten Serialisierungscode.
Seraphim
Oh, das hat perfekt funktioniert. Es hat mir so viel Kesselplattencode erspart. danke
iam.Carrot
56

Wenn müssen Sie es in einer Zeichenfolge tun (zB: in Ihre Ressourcen) , die Sie verwenden müssen , xml:space="preserve" und die Zeichen - Zeichen - Codes:

<System:String x:Key="TwoLiner" xml:space="preserve">First line&#10;Second line</System:String>

Oder wörtliche Zeilenumbrüche im Text:

<System:String x:Key="TwoLiner" xml:space="preserve">First line 
Second line</System:String>

Warnung: Wenn Sie Code wie im zweiten Beispiel schreiben, haben Sie entweder eine neue Zeile oder einen Wagenrücklauf und eine neue Zeile eingefügt, je nachdem, welche Zeilenenden Ihr Betriebssystem und / oder Ihr Texteditor verwenden. Wenn Sie das beispielsweise schreiben und es von einem Linux-System an git übergeben, scheint alles in Ordnung zu sein - aber wenn jemand es auf Windows klont, konvertiert git Ihre Zeilenenden in \r\nund abhängig davon, wofür Ihre Zeichenfolge für ... Sie bestimmt ist könnte die Welt brechen.

Seien Sie sich dessen bewusst, wenn Sie Leerzeichen beibehalten. Wenn Sie so etwas schreiben:

<System:String x:Key="TwoLiner" xml:space="preserve">
First line 
Second line 
</System:String>

Sie haben tatsächlich vier Zeilenumbrüche hinzugefügt, möglicherweise vier Zeilenumbrüche und möglicherweise nachfolgende Leerzeichen, die unsichtbar sind ...

Jaykul
quelle
10
Übrigens können Sie das xml:space="preserve"Attribut auch auf das anwenden ResourceDictionary, sodass Sie es nicht auf jede Ressourcenzeichenfolge anwenden müssen.
ocodo
1
Ohne das kaufmännische Und funktioniert auch. So etwas in der Art: <System:String x:Key="TwoLiner" xml:space="preserve">First line Second line</System:String> (mit einem Zeilenumbruch zwischen der ersten und der zweiten Zeile)
vgaltes
1
Ich wünschte, ich könnte Ihnen +10 fürxml:space="preserve"
TimothyP
1
@trooper Ich habe gerade die Bearbeitung vorgenommen und es wurde Jaykul / Mods Zustimmung überlassen. Und Jaykuls weitere Builds haben die kleinen Details hier wirklich klargestellt (da meine Bearbeitung nicht genau die gewünschte Ausgabe lieferte, wie gewünscht). Insgesamt würde ich sagen, dass diese Interaktion dazu beiträgt, noch bessere Antworten zu erstellen, anstatt meine eigenen zu veröffentlichen.
Anthony Lusardi
21

Sie müssen lediglich <TextBlock.Text>Ihre Inhalte wie folgt entfernen und hinzufügen:

    <Grid Margin="20">
        <TextBlock TextWrapping="Wrap" TextAlignment="Justify" FontSize="17">
        <Bold FontFamily="Segoe UI Light" FontSize="70">I.R. Iran</Bold><LineBreak/>
        <Span FontSize="35">I</Span>ran or Persia, officially the <Italic>Islamic Republic of Iran</Italic>, 
        is a country in Western Asia. The country is bordered on the 
        north by Armenia, Azerbaijan and Turkmenistan, with Kazakhstan and Russia 
        to the north across the Caspian Sea.<LineBreak/>
        <Span FontSize="10">For more information about Iran see <Hyperlink NavigateUri="http://en.WikiPedia.org/wiki/Iran">WikiPedia</Hyperlink></Span>
            <LineBreak/>
            <LineBreak/>
            <Span FontSize="12">
                <Span>Is this page helpful?</Span>
                <Button Content="No"/>
                <Button Content="Yes"/>
            </Span>
    </TextBlock>
    </Grid>

Geben Sie hier die Bildbeschreibung ein

SMMousavi
quelle
Und die Frage war " Wie kann ich Text einen Zeilenumbruch hinzufügen, wenn er als Attribut festgelegt wird ", Attribut, nicht Element.
Minuten
15

Beachten Sie, dass Sie dies im Textattribut tun müssen, ohne den Inhalt wie verwenden zu können

<TextBlock>Stuff on line1&#x0a;Stuff on line 2</TextBlock>

quelle
12

Vielleicht bevorzugt jemand

<TextBlock Text="{Binding StringFormat='Stuff on line1{0}Stuff on line2{0}Stuff on line3',
                          Source={x:Static s:Environment.NewLine}}" />

mit xmlns:s="clr-namespace:System;assembly=mscorlib".

LPL
quelle
Obwohl & # x0a; scheint mit XAML zu funktionieren, nicht mit Code. Dieser tut es.
FDF
11

Für diejenigen, die jede Antwort auf diese Frage ausprobiert haben und sich immer noch am Kopf kratzen, warum keiner von ihnen für Sie arbeitet, sind Sie möglicherweise auf eine Form des Problems gestoßen, auf das ich gestoßen bin.

Meine TextBlock.TextEigenschaft befand sich innerhalb eines ToolTipService.ToolTipElements und war an eine Eigenschaft eines Objekts gebunden, dessen Daten aus einer gespeicherten SQL-Prozedur abgerufen wurden. Jetzt wurden die Daten von dieser bestimmten Eigenschaft innerhalb der gespeicherten Prozedur aus einer SQL-Funktion abgerufen.

Da für mich nichts funktioniert hatte, gab ich meine Suche auf und erstellte die folgende Konverterklasse:

public class NewLineConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var s = string.Empty;

        if (value.IsNotNull())
        {
            s = value.ToString();

            if (s.Contains("\\r\\n"))
                s = s.Replace("\\r\\n", Environment.NewLine);

            if (s.Contains("\\n"))
                s = s.Replace("\\n", Environment.NewLine);

            if (s.Contains("&#x0a;&#x0d;"))
                s = s.Replace("&#x0a;&#x0d;", Environment.NewLine);

            if (s.Contains("&#x0a;"))
                s = s.Replace("&#x0a;", Environment.NewLine);

            if (s.Contains("&#x0d;"))
                s = s.Replace("&#x0d;", Environment.NewLine);

            if (s.Contains("&#10;&#13;"))
                s = s.Replace("&#10;&#13;", Environment.NewLine);

            if (s.Contains("&#10;"))
                s = s.Replace("&#10;", Environment.NewLine);

            if (s.Contains("&#13;"))
                s = s.Replace("&#13;", Environment.NewLine);

            if (s.Contains("<br />"))
                s = s.Replace("<br />", Environment.NewLine);

            if (s.Contains("<LineBreak />"))
                s = s.Replace("<LineBreak />", Environment.NewLine);
        }

        return s;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Am Ende musste ich die Enivornment.NewLineMethode aus der Antwort von @ dparker verwenden . Ich habe den Konverter angewiesen, nach einer möglichen Textdarstellung einer Newline zu suchen und diese durch zu ersetzen Environment.NewLine.

Das hat funktioniert!

Ich war jedoch immer noch ratlos darüber, warum keine der anderen Methoden mit datengebundenen Eigenschaften arbeitete.

Ich habe einen Kommentar zu @ BobKings akzeptierter Antwort hinterlassen :

@BobKing - Dies scheint im ToolTipService.ToolTip nicht zu funktionieren, wenn eine Bindung an ein Feld erfolgt, in das die Zeilenvorschübe aus einem SQL-Sproc eingebettet sind.

Er antwortete mit:

@CodeMaverick Wenn Sie mit eingebetteten neuen Zeilen an Text binden, sollten diese wahrscheinlich echte Zeichen-10-Werte (oder 13-Werte) und nicht die XML-Sentinels sein. Dies ist nur möglich, wenn Sie neue Zeilen in XAML-Dateien schreiben möchten.

Eine Glühbirne ging aus!

Ich ging in meine SQL-Funktion, ersetzte meine Textdarstellungen von Zeilenumbrüchen durch ...

CHAR( 13 ) + CHAR( 10 )

... den Konverter von meiner TextBlock.TextBindung entfernt und einfach so ... es hat funktioniert!

Code Maverick
quelle
9

Ich habe dies als hilfreich empfunden, bin jedoch beim Hinzufügen zu einem "Content = ..." - Tag in XAML auf einige Fehler gestoßen.

Ich hatte mehrere Zeilen im Inhalt und fand später heraus, dass der Inhalt Leerzeichen enthielt, obwohl ich das nicht spezifizierte. Um das zu umgehen und das Leerzeichen "ignorieren" zu lassen, habe ich so etwas implementiert.

<ToolTip Width="200" Style="{StaticResource ToolTip}" 
         Content="'Text Line 1' 
                   &#x0a;&#x0d;'Text Line 2' 
                   &#x0a;&#x0d;'Text Line 3'"/>

hoffe, das hilft jemand anderem.

(Die Ausgabe enthält drei Textzeilen mit einer leeren Zeile dazwischen.)

Neville
quelle
Vielleicht ist es besser, wenn Sie <ToolTip> <ToolTip.Content> <TextBlock Text = '.....' /> </ ToolTip.Content> </ ToolTip>
Simon_Weaver
5

Mir ist klar, dass dies eine ältere Frage ist, aber ich wollte das nur hinzufügen

Environment.NewLine

funktioniert auch, wenn dies über Code erfolgt.

dparker
quelle
4
<TextBlock>
    Stuff on line1 <LineBreak/>
    Stuff on line2
</TextBlock>

Es ist nicht wichtig zu wissen, aber was Sie zwischen den TextBlock-Tags angeben, wird als Inline-Inhalt bezeichnet und geht in die TextBlock.Inlines-Eigenschaft, die eine InlineCollection ist und Elemente vom Typ Inline enthält. Unterklassen von Inline sind unter anderem Run und LineBreak. siehe TextBlock.Inlines

user829755
quelle
3

Funktioniert auch nicht mit

<TextBlock><TextBlock.Text>NO USING ABOVE TECHNIQUE HERE</TextBlock.Text>

Keine große Sache, nur nötig

<TextBlock Text="Cool &#x0a;Newline trick" />

stattdessen.

Batgar
quelle
1
<TextBox 
    Name="myTextBox" 
    TextWrapping="Wrap" 
    AcceptsReturn="True" 
    VerticalScrollBarVisibility="Visible" />
Ahmed Ghoneim
quelle
-1

Code hinter der Lösung

private void Button1_Click(object sender, RoutedEventArgs e)
{
    System.Text.StringBuilder myStringBuilder = new System.Text.StringBuilder();
    myStringBuilder.Append("Orange").AppendLine();
    myStringBuilder.Append("").AppendLine();
    myStringBuilder.Append("Apple").AppendLine();
    myStringBuilder.Append("Banana").AppendLine();
    myStringBuilder.Append("").AppendLine();
    myStringBuilder.Append("Plum").AppendLine();
    TextBox1.Text = myStringBuilder.ToString();
}
Danny Coleiro
quelle