Wstawianie znaku tabulacji do tekstu za pomocą C #


283

Buduję aplikacji gdzie mam uchwycić kilka wartości i budowania tekst z nimi Name, Ageitp

Wynikiem będzie zwykły tekst w formacie TextBox.

Staram się, aby te informacje pojawiały się w pewnym sensie columns, dlatego staram się je rozdzielić, tababy były bardziej przejrzyste.

Na przykład zamiast mieć:

Ann 26
Sarah 29
Paul 45

Chciałbym, aby wyświetlało się jako:

Ann zakładka 26 Sarah zakładka 29 Paweł tab 45

Czy masz jakieś wskazówki, jak insertwstawiać tabulatory do mojego tekstu?


Słowo ostrzeżenia ..... jeśli długość pola nazwy jest zbyt długa, nadal nie uda się ich wyrównać. „Ann” ma tylko 3 znaki. „Jeremiasz” to 8. Pojedyncza zakładka dodana do „Ann” może sprawić, że ## pojawi się przed końcem Jeremiasza. Sugerowałbym parsowanie według liczby znaków. „Podziel” spacją, dodawaj spacje do pierwszego elementu do 12 znaków, a NASTĘPNIE dodaj „26”. Jeśli masz nazwę, która może być dłuższa niż 12, dostosuj
KeachyPeenReturns

Właśnie przeczytałem komentarz KeachyPeenReturns po opublikowaniu rozwiązania. Jego uwaga jest poprawna, ale jego rozwiązanie jest niedoskonałe. Najlepsza odpowiedź jest już niepoprawna. Poświęć trochę czasu na przeczytanie mojego rozwiązania i zaktualizowanie statusu (NAJLEPSZA odpowiedź) na to pytanie. Zwykle nie publikuję tego typu komentarzy, ale pytanie jest bardzo stare.
schlebe

Odpowiedzi:



445

Hazar ma rację \t. Oto pełna lista znaków ucieczki dla C #:

\' za pojedynczy cytat.

\" za podwójną wycenę.

\\ dla odwrotnego ukośnika.

\0 dla znaku zerowego.

\a dla znaku ostrzegawczego.

\b dla backspace.

\f dla pliku danych.

\n dla nowej linii.

\r do zwrotu karetki.

\t dla poziomej karty.

\v dla pionowej zakładki.

\uxxxxdla wartości szesnastkowej znaku Unicode (np \u0020.).

\xjest taki sam jak \u, ale nie potrzebujesz początkowych zer (np \x20.).

\Uxxxxxxxx dla wartości szesnastkowej znaku Unicode (dłuższa forma potrzebna do generowania surogatów).


8
Gdzie znalazłeś te dane? Chciałbym wiedzieć w celach informacyjnych.
QueueHammer

@QueueHammer rom Jon Skeet sam, wydaje się ... devblogs.microsoft.com/csharpfaq/…
Leonard AB

74

Może być również użyteczny w użyciu String.Formatnp

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

17
To najlepsza odpowiedź, ponieważ kod mówi dłużej niż jeden linijka i długie objaśnienia.
Phil,

4
var text = "Ann@26"

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

2

Można to zrobić na kilka sposobów. Najprostszym jest użycie \tw tekście. Jest jednak możliwe, że \tnie działa w niektórych sytuacjach, takich jak PdfReportpakiet nuget.


4
Przydałoby się dodać informacje o tym, jak dodać kartę w przypadku, \tgdy nie działa. ;)
J. Scott Elblein

2

Za pomocą Microsoft Winform controlsnie można poprawnie rozwiązać problemu bez małego obejścia, które wyjaśnię poniżej.

PROBLEM

Problem z prostym użyciem "\t"lub vbTabpolega na tym, że gdy wyświetla się więcej niż jeden TextBox i że wyrównanie musi być przestrzegane dla wszystkich TextBox, TYLKO "\t"lub vbTabrozwiązanie wyświetli coś, co NIE ZAWSZE jest poprawnie wyrównane.

Przykład w 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

wyświetli się

wprowadź opis zdjęcia tutaj

jak widać, agewartość for François-Victorjest przesunięta w prawo i nie jest wyrównana z agewartością dwóch innych TextBox.

ROZWIĄZANIE

Aby rozwiązać ten problem, należy ustawić pozycję Tabs przy użyciu określonej SendMessage()funkcji API user32.dll, jak pokazano poniżej.

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

i wyświetlony zostanie następujący formularz

wprowadź opis zdjęcia tutaj

Teraz widać, że wszystkie wartości są poprawnie wyrównane :-)

UWAGI

MultilineWłaściwość TextBox musi być ustawiona na True . Jeśli ta właściwość jest ustawiona na False, karta jest pozycjonowana jak poprzednio.

Sposób AcceptsTabprzypisania własności nie jest ważny (przetestowałem).

To pytanie zostało już potraktowane na StackOverflow

Uwaga: jednostka miary dla pozycji Tab nie jest znakiem, ale czymś, co wydaje się mieć 1/4 znaku. Dlatego mnożę długość przez 4.

C # ROZWIĄZANIE

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;

Działa to dobrze, ale musisz mieć czcionkę o jednolitym odstępie.


1

Przy użyciu literalnych ciągów znaków (zacznij od @ ”) może to być łatwiejsze

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

Spowodowałoby to Apple:<tab>Bob


1

Oprócz powyższych odpowiedzi możesz użyć PadLeft lub PadRight:

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

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

Spowoduje to wypełnienie ciągu spacjami po lewej lub prawej stronie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.