Inserindo um caractere de tabulação no texto usando C #


283

Estou construindo uma aplicação onde eu deveria capturar vários valores e construir um texto com eles: Name, Age, etc.

A saída será um texto sem formatação em a TextBox.

Estou tentando fazer com que essas informações apareçam columns, portanto, estou tentando separá-las tabpara torná-las mais claras.

Por exemplo, em vez de ter:

Ann 26
Sarah 29
Paul 45

Gostaria que ele mostrasse como:

Ann tab 26 Sarah tab 29 Paul tab 45

Alguma dica sobre como insertas guias no meu texto?


Uma palavra de aviso ..... se o comprimento do campo de nome for muito longo, você ainda não conseguirá que eles se alinhem. "Ann" tem apenas 3 caracteres. "Jeremiah" é 8. Uma única guia adicionada a "Ann" pode fazer com que o ## apareça antes do final da jeremiah. Eu sugeriria a análise pelo número de caracteres. "Divida" por espaço, adicione espaços ao primeiro membro até 12 caracteres e, em seguida, adicione "26". Se você tiver um nome com mais de 12 anos, ajuste
#

Acabei de ler o comentário do KeachyPeenReturns depois de ter postado uma solução. Sua observação está correta, mas sua solução é imperfeita. A resposta BEST já está incorreta. Reserve um tempo para ler minha solução e atualizar o status (melhor resposta) para esta pergunta. Normalmente, eu não publico esse tipo de comentário, mas a pergunta é muito antiga.
schlebe

Respostas:



445

Hazar está certo com o dele \t. Aqui está a lista completa de caracteres de escape para C #:

\' para uma única citação.

\" para uma citação dupla.

\\ para uma barra invertida.

\0 para um caractere nulo.

\a para um caractere de alerta.

\b para um backspace.

\f para um feed de formulário.

\n para uma nova linha.

\r para um retorno de carro.

\t para uma guia horizontal.

\v para uma guia vertical.

\uxxxxpara um valor hexadecimal de caracteres unicode (por exemplo \u0020).

\xé o mesmo que \u, mas você não precisa de zeros à esquerda (por exemplo \x20).

\Uxxxxxxxx para um valor hexadecimal de caractere unicode (é necessário um formato mais longo para gerar substitutos).


8
Onde você encontrou esses dados? Eu gostaria de saber para minha referência.
QueueHammer

@QueueHammer do próprio Jon Skeet, parece ... devblogs.microsoft.com/csharpfaq/…
Leonard AB

74

Também pode ser útil String.Format, por exemplo

String.Format("{0}\t{1}", FirstName,Count);

17
Esta é a melhor resposta porque o código fala mais do que um forros e explicações longas.
Phil

4
var text = "Ann@26"

var editedText = text.Replace("@", "\t");

2

Há várias maneiras de fazer isso. O mais simples é usar \tno seu texto. No entanto, é possível que \tisso não funcione em algumas situações, como o PdfReportpacote nuget.


4
Seria útil adicionar informações sobre como adicionar uma guia no caso em \tque não funciona. ;)
J. Scott Elblein

2

Usando Microsoft Winform controls, é impossível resolver corretamente o seu problema sem uma pequena solução alternativa que explicarei abaixo.

PROBLEMA

O problema do uso simples "\t"ou vbTabé que, quando mais de um TextBox são exibidos e esse alinhamento deve ser respeitado para todos os TextBox, o ONLY "\t"ou a vbTabsolução exibirá algo que NÃO SEMPRE está alinhado corretamente.

Exemplo no VB.Net:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    TextBox1.Text = "Bernard" + vbTab + "32"
    TextBox2.Text = "Luc" + vbTab + "47"
    TextBox3.Text = "François-Victor" + vbTab + "12"
End Sub

Exibirá

insira a descrição da imagem aqui

como você pode ver, o agevalor de François-Victoré deslocado para a direita e não está alinhado com o agevalor de outros dois TextBox.

SOLUÇÃO

Para resolver esse problema, você deve definir a posição das guias usando uma SendMessage()função específica da API user32.dll, conforme mostrado abaixo.

Public Class Form1

    Public Declare Function SendMessage _
        Lib "user32" Alias "SendMessageA" _
        ( ByVal hWnd As IntPtr _
        , ByVal wMsg As Integer _
        , ByVal wParam As Integer _
        , ByVal lParam() As Integer _
        ) As Integer

    Private Const EM_SETTABSTOPS As Integer = &HCB

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim tabs() As Integer = {4 * 25}

        TextBox1.Text = "Bernard" + vbTab + "32"
        SendMessage(TextBox1.Handle, EM_SETTABSTOPS, 1, tabs)
        TextBox2.Text = "Luc" + vbTab + "47"
        SendMessage(TextBox2.Handle, EM_SETTABSTOPS, 1, tabs)
        TextBox3.Text = "François-Victor" + vbTab + "12"
        SendMessage(TextBox3.Handle, EM_SETTABSTOPS, 1, tabs)
    End Sub

End Class

e o formulário a seguir será exibido

insira a descrição da imagem aqui

Você pode ver que agora, todos os valores estão alinhados corretamente :-)

OBSERVAÇÕES

MultilineA propriedade TextBox deve ser definida como True . Se essas propriedades estiverem definidas como Falso, a guia estará posicionada como antes.

Como a AcceptsTabpropriedade é atribuída não é importante (eu testei).

Esta questão já foi tratada no StackOverflow

Cuidado: a unidade de medida para a posição da guia não é caractere, mas algo que parece ter 1/4 de caractere. É por isso que multiplico o comprimento por 4.

SOLUÇÃO C #

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, uint[] lParam);
        private const int EM_SETTABSTOPS = 0x00CB;
        private const char vbTab = '\t';

        public Form1()
        {
            InitializeComponent();

            var tabs = new uint[] { 25 * 4 };

            textBox1.Text = "Bernard" + vbTab + "32";
            SendMessage(textBox1.Handle, EM_SETTABSTOPS, 1, tabs);
            textBox2.Text = "Luc" + vbTab + "47";
            SendMessage(textBox2.Handle, EM_SETTABSTOPS, 1, tabs);
            textBox3.Text = "François-Victor" + vbTab + "12";
            SendMessage(textBox3.Handle, EM_SETTABSTOPS, 1, tabs);
        }
    }
}

1
string St = String.Format("{0,-20} {1,5:N1}\r", names[ctr], hours[ctr]);
richTextBox1.Text += St;

Isso funciona bem, mas você deve ter uma fonte com espaçamento simples.


1

Ao usar strings literais (comece com @ "), isso pode ser mais fácil

char tab = '\u0009';
string A = "Apple";
string B = "Bob";
string myStr = String.Format(@"{0}:{1}{2}", A, tab, B);

Resultaria em Apple:<tab>Bob


1

Além das respostas acima, você pode usar PadLeft ou PadRight:

string name = "John";
string surname = "Smith";

Console.WriteLine("Name:".PadRight(15)+"Surname:".PadRight(15));
Console.WriteLine( name.PadRight(15) + surname.PadRight(15));

Isso preencherá a sequência com espaços à esquerda ou à direita.

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.