Nova linha no atributo string

283

Como posso adicionar uma quebra de linha ao texto quando ele está sendo definido como um atributo, ou seja:

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

Dividi-lo no formato explodido não é uma opção para minha situação específica. O que eu preciso é de uma maneira de emular o seguinte:

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

Respostas:

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

Você pode usar qualquer valor codificado hexadecimalmente para representar um literal. Nesse caso, usei o feed de linha (caractere 10). Se você quer fazer "clássico" vbCrLf, pode usar&#x0d;&#x0a;

A propósito, observe a sintaxe: é o e comercial, uma libra, a letra x , o valor hexadecimal do caractere que você deseja e, finalmente, um ponto e vírgula.

TAMBÉM: Para garantir a integridade, é possível vincular a um texto que já tenha os feeds de linha incorporados, como uma constante em seu código ou uma variável construída em tempo de execução.

Bob King
fonte
14
Aparentemente, isso não funciona nas tags <TextBlock.Text> </ TextBlock.Text>.
Tcables
45
Até hoje, tenho 34 votos positivos para essa resposta e ainda precisava voltar e verificar, porque a sintaxe é tão arcaica.
Bob King
3
Absolutamente. Eu tenho este favorito. Eu tenho que vir verificar o tempo todo.
MojoFilter
4
'Arcaico' ==> 'Arcano' :-)
Will Dean
5
Funciona mesmo dentro de um parâmetro de ligação ao adicionar uma barra invertida como: ConverterParameter = 'Test \ & # x0a; Text'
Sven
72

Pode ser que você possa usar o atributo xml: space = "preserve" para preservar espaços em branco no XAML de origem

<TextBlock xml:space="preserve">
Stuff on line 1
Stuff on line 2
</TextBlock>
scrat789
fonte
8
Você também pode remover xml: space = "preserve" e adicionar <LineBreak /> entre as linhas
usefulBee
5
Deve-se notar (alguns anos depois) que xml:space="preserve"também manterá os espaços de recuo, que geralmente estão presentes no XAML. Assim, um explícito, <LineBreak />como sugerido acima, parece ser uma solução mais limpa.
Zeus
Obrigado! Esta solução se encaixou muito bem no meu código de serialização baseado em XAML.
Seraphim
Oh, isso funcionou perfeitamente. Isso me salvou muito código da placa da caldeira. graças
iam.Carrot
57

Quando você precisar fazer isso em uma string (por exemplo: em seus recursos), precisará usar os códigos de caracteres xml:space="preserve" e comercial:

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

Ou novas linhas literais no texto:

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

Aviso: se você escrever código como o segundo exemplo, você inseriu quer uma nova linha ou um retorno de carro e nova linha, dependendo dos fins de linha o seu sistema operacional e / ou uso editor de texto. Por exemplo, se você escrever isso e o comprometer com o git a partir de um sistema Linux, tudo poderá parecer bem - mas se alguém o clonar no Windows, o git converterá as terminações da sua linha para \r\ne dependendo da sua string ... pode quebrar o mundo.

Esteja ciente disso quando estiver preservando espaços em branco. Se você escrever algo como isto:

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

Na verdade, você adicionou quatro quebras de linha, possivelmente quatro retornos de carro e espaço em branco potencialmente invisível ...

Jaykul
fonte
10
BTW, você pode apenas aplicar o xml:space="preserve"atributo ao ResourceDictionarytambém, para não precisar aplicá-lo a todas as cadeias de recursos.
ocodo 23/02
1
Sem o e comercial também funciona. Algo parecido com isto: <System:String x:Key="TwoLiner" xml:space="preserve">First line Second line</System:String> (com uma quebra de linha entre Primeira linha e Segunda linha)
vgaltes 07/07
1
Eu gostaria de poder lhe dar +10 por #xml:space="preserve"
TimothyP 26/10
1
@trooper Acabei de fazer a edição e foi deixada até a aprovação de Jaykul / mod. E as compilações posteriores de Jaykul realmente esclareceram os pequenos detalhes aqui (já que minha edição não deu a saída desejada exatamente como queria). No geral, eu diria que essa interação ajuda a criar respostas ainda melhores, em vez de postar as minhas.
Anthony Lusardi 28/03
21

Você precisa apenas remover <TextBlock.Text>e simplesmente adicionar seu conteúdo da seguinte forma:

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

insira a descrição da imagem aqui

SMMousavi
fonte
E a pergunta era " Como posso adicionar uma quebra de linha ao texto quando ele está sendo definido como um atributo ", atributo, não elemento.
mins
15

Observe que, para fazer isso, você precisa fazê-lo no atributo Texto. Não é possível usar o conteúdo como

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

fonte
12

Talvez alguém prefira

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

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

LPL
fonte
Apesar de adicionar o & # x0a; parece funcionar no XAML, não no código. Este faz.
FDF 14/01
11

Para aqueles que tentaram todas as respostas a esta pergunta e ainda estão coçando a cabeça por que nenhum deles funciona para você, você pode ter encontrado uma forma do problema em que encontrei.

Minha TextBlock.Textpropriedade estava dentro de um ToolTipService.ToolTipelemento e estava vinculada a uma propriedade de um objeto cujos dados estavam sendo extraídos de um procedimento armazenado SQL. Agora, os dados dessa propriedade específica no procedimento armazenado estavam sendo extraídos de uma função SQL.

Como nada funcionou para mim, desisti da minha pesquisa e criei a classe do conversor abaixo:

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

Acabei tendo que usar o Enivornment.NewLinemétodo da resposta do @ dparker . Instruí o conversor a procurar qualquer representação textual possível de uma nova linha e substituí-la porEnvironment.NewLine .

Isso funcionou!

No entanto, eu ainda estava perplexo com o motivo de nenhum dos outros métodos trabalhar com propriedades de banco de dados.

Deixei um comentário na resposta aceita por @ BobKing :

@BobKing - Isso parece não funcionar no ToolTipService.ToolTip ao vincular a um campo que possui os feeds de linha incorporados a partir de um sproc SQL.

Ele respondeu com:

@CodeMaverick Se você está vinculando ao texto com as novas linhas incorporadas, elas provavelmente devem ter valores reais de 10 caracteres (ou 13) e não os sentinelas XML. Isso é apenas se você desejar escrever novas linhas literais em arquivos XAML.

Uma lâmpada se apagou!

Entrei na minha função SQL, substitui minhas representações textuais de novas linhas por ...

CHAR( 13 ) + CHAR( 10 )

... removeu o conversor da minha TextBlock.Textligação e, assim mesmo ... funcionou!

Code Maverick
fonte
9

Eu achei isso útil, mas encontrei alguns erros ao adicioná-lo a uma tag "Content = ..." no XAML.

Eu tinha várias linhas no conteúdo e, mais tarde, descobri que o conteúdo mantinha espaços em branco, apesar de não ter especificado isso. para contornar isso e fazer com que "ignore" o espaço em branco, eu implementei isso.

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

espero que isso ajude outra pessoa.

(A saída é tem as três linhas de texto com uma linha vazia entre cada uma.)

Neville
fonte
pode ser melhor tentar <ToolTip> <ToolTip.Content> <TextBlock Text = '.....' /> </ ToolTip.Content> </ToolTip>
Simon_Weaver
5

Sei que isso está em questão mais antiga, mas só queria acrescentar que

Environment.NewLine

também funciona se fizer isso através do código.

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

não é importante saber, mas o que você especifica entre as tags TextBlock é chamado de conteúdo embutido e entra na propriedade TextBlock.Inlines, que é um InlineCollection e contém itens do tipo Inline. As subclasses de Inline são Run e LineBreak, entre outras. consulte TextBlock.Inlines

user829755
fonte
3

Também não funciona com

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

Não é grande coisa, só precisava usar

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

em vez de.

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

Código por trás da solução

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
fonte