Insertar un carácter de tabulación en el texto usando C #

283

Estoy construyendo una aplicación en la que debería capturar varios valores y construir un texto con ellos: Name, Age, etc.

La salida será un texto plano en un TextBox.

Estoy tratando de hacer que esa información aparezca en una especie de columns, por lo tanto, estoy tratando de separarlos tabpara que sea más clara.

Por ejemplo, en lugar de tener:

Ann 26
Sarah 29
Paul 45

Me gustaría que se muestre como:

Ann pestaña 26 Sarah pestaña 29 Paul pestaña 45

¿Algún consejo sobre cómo insertlas pestañas en mi texto?

Layla
fuente
Una palabra de advertencia ... si la longitud del campo de nombre es demasiado larga, todavía no podrá alinearlos. "Ann" tiene solo 3 caracteres. "Jeremiah" es 8. Una sola pestaña agregada a "Ann" podría hacer que aparezca ## antes del final de jeremiah. Sugeriría el análisis por número de caracteres. "Dividir" por espacio, agregar espacios al primer miembro hasta 12 caracteres y ENTONCES agregar "26". Si tiene un nombre que puede ser más largo que 12, ajuste
KeachyPeenReturns
Acabo de leer el comentario de KeachyPeenReturns después de haber publicado una solución. Su comentario es correcto pero su solución es imperfecta. La MEJOR respuesta ya es incorrecta. Tómese el tiempo para leer mi solución y actualizar el estado (MEJOR respuesta) para esta pregunta. Normalmente, no publico este tipo de comentario, pero la pregunta es muy antigua.
schlebe

Respuestas:

460

Intenta usar el \tpersonaje en tus cadenas

DShook
fuente
445

Hazar tiene razón con la suya \t. Aquí está la lista completa de caracteres de escape para C #:

\' Por una sola cita.

\" por una cita doble

\\ para una barra invertida.

\0 para un personaje nulo.

\a para un personaje alerta.

\b para un retroceso.

\f para un formulario de alimentación.

\n para una nueva línea

\r para un retorno de carro.

\t para una pestaña horizontal.

\v para una pestaña vertical.

\uxxxxpara un valor hexadecimal de caracteres unicode (por ejemplo \u0020).

\xes lo mismo que \u, pero no necesita ceros a la izquierda (p \x20. ej .).

\Uxxxxxxxx para un valor hexadecimal de caracteres unicode (se necesita una forma más larga para generar sustitutos).

Dan R
fuente
8
¿Dónde encontraste estos datos? Me gustaría saber para mi referencia.
QueueHammer
@QueueHammer rom Jon Skeet mismo, parece ... devblogs.microsoft.com/csharpfaq/…
Leonard AB
74

También puede ser útil de usar String.Format, p. Ej.

String.Format("{0}\t{1}", FirstName,Count);
david valentine
fuente
17
Esta es la mejor respuesta porque el código habla más de una línea y explicaciones largas.
Phil
4
var text = "Ann@26"

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

Hay varias formas de hacerlo. Lo más simple es usarlo \ten su texto. Sin embargo, es posible que \tno funcione en algunas situaciones, como el PdfReportpaquete nuget.

Amin Saqi
fuente
44
Sería útil agregar información sobre cómo agregar una pestaña en el caso de \tque no funcione. ;)
J. Scott Elblein el
2

Utilizando Microsoft Winform controls, es imposible resolver correctamente su problema sin una pequeña solución que explicaré a continuación.

PROBLEMA

El problema al usar simplemente "\t"o vbTabes que cuando se muestra más de un TextBox y se debe respetar la alineación para todos los TextBox, SOLO "\t"o la vbTabsolución mostrará algo que NO SIEMPRE está correctamente alineado.

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

mostrará

ingrese la descripción de la imagen aquí

Como puede ver, el agevalor de François-Victorse desplaza hacia la derecha y no está alineado con el agevalor de otros dos cuadros de texto.

SOLUCIÓN

Para resolver este problema, debe establecer la posición de las pestañas utilizando una función específica de la SendMessage()API user32.dll como se muestra a continuación.

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

y se mostrará el siguiente formulario

ingrese la descripción de la imagen aquí

Puede ver que ahora, todos los valores están correctamente alineados :-)

OBSERVACIONES

MultilineLa propiedad de TextBox debe establecerse en True . Si esta propiedad se establece en False, la pestaña se coloca como antes.

Cómo AcceptsTabse asigna la propiedad no es importante (lo he probado).

Esta pregunta ya se ha tratado en StackOverflow

Precaución: la unidad de medida para la posición de tabulación no es un carácter, sino algo que parece ser 1/4 de carácter. Por eso multiplico la longitud por 4.

SOLUCIÓN 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);
        }
    }
}
Schlebe
fuente
1
string St = String.Format("{0,-20} {1,5:N1}\r", names[ctr], hours[ctr]);
richTextBox1.Text += St;

Esto funciona bien, pero debe tener una fuente monoespaciada.

CERI
fuente
1

Al usar cadenas literales (comience con @ ") esto podría ser más fácil

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

Resultaría en Apple:<tab>Bob

Hecatonchires
fuente
1

Además de las respuestas anteriores, puede usar PadLeft o PadRight:

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

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

Esto llenará la cadena con espacios a la izquierda o derecha.

Heersert
fuente