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

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.


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>

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


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


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>

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


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!


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


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.


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


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.


1
<TextBox 
    Name="myTextBox" 
    TextWrapping="Wrap" 
    AcceptsReturn="True" 
    VerticalScrollBarVisibility="Visible" />

-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();
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.