Inserimento di un carattere di tabulazione nel testo usando C #


284

Sto costruendo una domanda in cui dovrei catturare diversi valori e costruire un testo con loro: Name, Age, etc.

L'output sarà un semplice testo in a TextBox.

Sto cercando di far apparire tali informazioni in qualche modo columns, quindi sto cercando di separarle tabper renderle più chiare.

Ad esempio, invece di avere:

Ann 26
Sarah 29
Paul 45

Vorrei che fosse mostrato come:

Ann scheda 26 Sarah scheda 29 Paul scheda 45

Qualche suggerimento su come insertinserire le schede nel mio testo?


Un avvertimento ..... se la lunghezza del campo del nome è troppo lunga, non riuscirai comunque ad allinearli. "Ann" ha solo 3 caratteri. "Geremia" è 8. Una singola scheda aggiunta a "Ann" potrebbe far apparire ## prima della fine di Geremia. Vorrei suggerire l'analisi per numero di caratteri. "Dividi" per spazio, aggiungi spazi al primo membro fino a 12 caratteri, quindi aggiungi "26". Se hai un nome che potrebbe essere più lungo di 12, modifica
KeachyPeen Restituisce il

Ho appena letto il commento di KeachyPeenReturns dopo aver pubblicato una soluzione. La sua osservazione è corretta ma la sua soluzione è imperfetta. La risposta MIGLIORE è già errata. Prenditi del tempo per leggere la mia soluzione e aggiornare lo stato (MIGLIORE risposta) per questa domanda. Normalmente, non pubblico questo tipo di commento ma la domanda è molto vecchia.
schlebe,

Risposte:


461

Prova a usare il \tpersonaggio nelle tue stringhe


445

Hazar ha ragione con il suo \t. Ecco l'elenco completo dei caratteri di escape per C #:

\' per una singola citazione.

\" per una doppia citazione.

\\ per una barra rovesciata.

\0 per un carattere nullo.

\a per un personaggio attento.

\b per un backspace.

\f per un feed di moduli.

\n per una nuova linea.

\r per un ritorno a capo.

\t per una scheda orizzontale.

\v per una scheda verticale.

\uxxxxper un valore esadecimale di carattere unicode (ad es \u0020.).

\xè lo stesso di \u, ma non hai bisogno di zeri iniziali (ad es \x20.).

\Uxxxxxxxx per un valore esadecimale di carattere unicode (è necessaria una forma più lunga per generare surrogati).


8
Dove hai trovato questi dati? Vorrei sapere come riferimento.
QueueHammer,

@QueueHammer da Jon Skeet in persona, sembra ... devblogs.microsoft.com/csharpfaq/…
Leonard AB

74

Può anche essere utile da usare String.Format, ad es

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

17
Questa è la risposta migliore perché il codice parla più di una riga e lunghe spiegazioni.
Phil

4
var text = "Ann@26"

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

2

Ci sono molti modi per farlo. Il più semplice sta usando \tnel tuo testo. Tuttavia, è possibile che \tnon funzioni in alcune situazioni, come il PdfReportpacchetto nuget.


4
Sarebbe utile aggiungere informazioni su come aggiungere una scheda nel caso in cui \tnon funzioni. ;)
J. Scott Elblein,

2

Usando Microsoft Winform controls, è impossibile risolvere correttamente il tuo problema senza una piccola soluzione che spiegherò di seguito.

PROBLEMA

Il problema nell'uso semplice "\t"o vbTabè che quando vengono visualizzati più di un TextBox e tale allineamento deve essere rispettato per tutti i TextBox, l'UNICO "\t"o la vbTabsoluzione visualizzeranno qualcosa che NON È SEMPRE allineato correttamente.

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

verrà visualizzato

inserisci qui la descrizione dell'immagine

come puoi vedere, agevalue for François-Victorviene spostato a destra e non è allineato con il agevalore di altri due TextBox.

SOLUZIONE

Per risolvere questo problema, è necessario impostare la posizione delle schede utilizzando una SendMessage()funzione API user32.dll specifica come mostrato di seguito.

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 verrà visualizzato il seguente modulo

inserisci qui la descrizione dell'immagine

Ora puoi vedere che tutti i valori sono allineati correttamente :-)

OSSERVAZIONI

MultilineLa proprietà di TextBox deve essere impostata su True . Se questa proprietà è impostata su False, la scheda viene posizionata come prima.

Come la AcceptsTabproprietà è assegnata non è importante (ho testato).

Questa domanda è già stata trattata su StackOverflow

Attenzione: l'unità di misura per la posizione della scheda non è carattere ma qualcosa che sembra essere 1/4 di carattere. Ecco perché moltiplico la lunghezza per 4.

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

Funziona bene, ma devi avere un carattere mono-spaziato.


1

Quando si utilizzano stringhe letterali (iniziare con @ ") questo potrebbe essere più semplice

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

Ne deriverebbe Apple:<tab>Bob


1

Oltre alle risposte sopra puoi usare 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));

Questo riempirà la stringa con spazi a sinistra o a destra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.