Nouvelle ligne dans l'attribut de chaîne

283

Comment puis-je ajouter un saut de ligne au texte lorsqu'il est défini comme attribut, c'est-à-dire:

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

Le décomposer en format éclaté n'est pas une option pour ma situation particulière. Ce dont j'ai besoin, c'est d'un moyen d'imiter les éléments suivants:

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

Réponses:

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

Vous pouvez utiliser n'importe quelle valeur codée hexadécimale pour représenter un littéral. Dans ce cas, j'ai utilisé le saut de ligne (caractère 10). Si vous voulez faire "classique" vbCrLf, vous pouvez utiliser&#x0d;&#x0a;

Soit dit en passant, notez la syntaxe: c'est l'esperluette, une livre, la lettre x , puis la valeur hexadécimale du caractère que vous voulez, et enfin un point-virgule.

AUSSI: Pour être complet, vous pouvez lier à un texte qui contient déjà les sauts de ligne comme une constante dans votre code derrière, ou une variable construite à l'exécution.

Bob King
la source
14
Apparemment, cela ne fonctionne pas dans les balises <TextBlock.Text> </ TextBlock.Text>.
tcables
45
À ce jour, j'ai 34 votes positifs sur cette réponse, et je devais encore revenir et vérifier parce que la syntaxe est tellement archaïque.
Bob King
3
Absolument. J'ai ce signet. Je dois venir le vérifier tout le temps.
MojoFilter
4
'Archaic' ==> 'Arcane' :-)
Will Dean
5
Fonctionne même à l'intérieur d'un paramètre de liaison lors de l'ajout d'une barre oblique inverse comme: ConverterParameter = 'Test \ & # x0a; Text'
Sven
72

Peut-être que vous pouvez utiliser l'attribut xml: space = "preserve" pour préserver les espaces dans le XAML source

<TextBlock xml:space="preserve">
Stuff on line 1
Stuff on line 2
</TextBlock>
scrat789
la source
8
Vous pouvez également supprimer xml: space = "preserve" et ajouter <LineBreak /> entre les lignes
utileBee
5
Il convient de noter (quelques années plus tard) que xml:space="preserve"l'on conservera également les espaces de retrait, qui sont généralement présents dans XAML. Ainsi, une explicite <LineBreak />comme suggéré ci-dessus semble être une solution plus propre.
Zeus
Merci! Cette solution s'est très bien adaptée à mon code de sérialisation basé sur XAML.
Seraphim
Oh, cela a fonctionné parfaitement. Cela m'a sauvé tellement de code de plaque de chaudière. merci
iam.Carrot
57

Lorsque vous avez besoin de le faire dans une chaîne (par exemple: dans vos ressources) , vous devez utiliser xml:space="preserve" et les codes de esperluette:

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

Ou des nouvelles lignes littérales dans le texte:

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

Avertissement: si vous écrivez du code comme dans le deuxième exemple, vous avez inséré soit une nouvelle ligne, soit un retour chariot et une nouvelle ligne, selon les fins de ligne utilisées par votre système d'exploitation et / ou l'éditeur de texte. Par exemple, si vous écrivez cela et le validez dans git à partir d'un système Linux, tout peut sembler correct - mais si quelqu'un le clone vers Windows, git convertira vos fins de ligne en \r\net en fonction de la destination de votre chaîne ... vous pourrait briser le monde.

Soyez conscient de cela lorsque vous préservez des espaces. Si vous écrivez quelque chose comme ça:

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

Vous avez en fait ajouté quatre sauts de ligne, peut-être quatre retours chariot, et éventuellement un espace blanc à la fin qui est invisible ...

Jaykul
la source
10
BTW, vous pouvez simplement appliquer l' xml:space="preserve"attribut à ResourceDictionarytrop, de sorte que vous n'avez pas besoin de l'appliquer à chaque chaîne de ressource.
ocodo
1
Sans l'esperluette fonctionne également. Quelque chose comme ça: <System:String x:Key="TwoLiner" xml:space="preserve">First line Second line</System:String> (avec un saut de ligne entre la première ligne et la deuxième ligne)
vgaltes
1
J'aimerais pouvoir vous donner +10 pourxml:space="preserve"
TimothyP
1
@trooper Je viens de faire le montage et il a été laissé à l'approbation de Jaykul / mod. Et les versions ultérieures de Jaykul ont vraiment clarifié les détails mineurs ici (car mon montage n'a pas donné la sortie souhaitée exactement comme souhaitée). Dans l'ensemble, je dirais que cette interaction permet de créer de meilleures réponses plutôt que de publier les miennes.
Anthony Lusardi
21

Vous devez simplement supprimer <TextBlock.Text>et simplement ajouter votre contenu comme suit:

    <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>

entrez la description de l'image ici

SMMousavi
la source
Et la question était " Comment puis-je ajouter un saut de ligne au texte lorsqu'il est défini comme un attribut ", attribut, pas élément.
min
15

Notez que pour ce faire, vous devez le faire dans l'attribut Text, vous ne pouvez pas utiliser le contenu comme

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

la source
12

Peut-être que quelqu'un préfère

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

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

LPL
la source
Bien que l’ajout de & # x0a; semble fonctionner à partir de XAML, il ne fonctionne pas à partir du code. Celui-ci le fait.
FDF
11

Pour ceux qui ont essayé toutes les réponses à cette question et se grattent toujours la tête pour savoir pourquoi aucun d'entre eux ne fonctionne pour vous, vous avez peut-être rencontré une forme du problème que j'ai rencontré.

Ma TextBlock.Textpropriété était à l'intérieur d'un ToolTipService.ToolTipélément et elle était liée à une propriété d'un objet dont les données étaient extraites d'une procédure stockée SQL. À présent, les données de cette propriété particulière dans la procédure stockée étaient extraites d'une fonction SQL.

Comme rien n'avait fonctionné pour moi, j'ai abandonné ma recherche et créé la classe de convertisseur ci-dessous:

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();
    }
}

J'ai fini par devoir utiliser la Enivornment.NewLineméthode de la réponse de @ dparker . J'ai demandé au convertisseur de rechercher toute représentation textuelle possible d'une nouvelle ligne et de la remplacer par Environment.NewLine.

Ça a marché!

Cependant, j'étais toujours perplexe quant à la raison pour laquelle aucune des autres méthodes ne fonctionnait avec des propriétés de databound.

J'ai laissé un commentaire sur la réponse acceptée de @ BobKing :

@BobKing - Cela ne semble pas fonctionner dans ToolTipService.ToolTip lors de la liaison à un champ dont les sauts de ligne sont intégrés à partir d'un sproc SQL.

Il a répondu par:

@CodeMaverick Si vous liez au texte avec les nouvelles lignes incorporées, elles devraient probablement être de vraies valeurs de 10 caractères (ou 13) et non les sentinelles XML. C'est seulement si vous voulez écrire de nouvelles lignes littérales dans des fichiers XAML.

Une ampoule s'est éteinte!

Je suis entré dans ma fonction SQL, remplacé mes représentations textuelles de sauts de ligne par ...

CHAR( 13 ) + CHAR( 10 )

... retiré le convertisseur de ma TextBlock.Textreliure, et juste comme ça ... ça a marché!

Code Maverick
la source
9

J'ai trouvé cela utile, mais j'ai rencontré quelques erreurs lors de l'ajout à une balise "Content = ..." dans XAML.

J'avais plusieurs lignes dans le contenu et j'ai découvert plus tard que le contenu conservait des espaces blancs même si je ne l'avais pas spécifié. donc pour contourner cela et l'avoir "ignorer" l'espace blanc, j'ai implémenté comme ça.

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

J'espère que ceci aide quelqu'un d'autre.

(La sortie est composée de trois lignes de texte avec une ligne vide entre chacune.)

Neville
la source
il vaut mieux essayer <ToolTip> <ToolTip.Content> <TextBlock Text = '.....' /> </ ToolTip.Content> </ToolTip>
Simon_Weaver
5

Je me rends compte que c'est sur une question plus ancienne mais je voulais juste ajouter que

Environment.NewLine

fonctionne également si vous le faites via du code.

dparker
la source
4
<TextBlock>
    Stuff on line1 <LineBreak/>
    Stuff on line2
</TextBlock>

ce n'est pas qu'il est important de savoir, mais ce que vous spécifiez entre les balises TextBlock est appelé contenu en ligne et va dans la propriété TextBlock.Inlines qui est un InlineCollection et contient des éléments de type Inline. Les sous-classes d'Inline sont Run et LineBreak, entre autres. voir TextBlock.Inlines

user829755
la source
3

Ne fonctionne pas non plus avec

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

Pas grand-chose, juste besoin d'utiliser

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

au lieu.

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

Code derrière la solution

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
la source