Existe-t-il un moyen simple de créer deux colonnes dans une fenêtre de texte contextuelle?

StackOverflow https://stackoverflow.com/questions/72198

Question

Cela semblait être une chose facile à faire. Je voulais simplement faire apparaître une fenêtre de texte et afficher deux colonnes de données - une description à gauche et une valeur correspondante à droite. Je n'ai pas beaucoup travaillé avec Forms, alors j'ai simplement saisi le premier contrôle qui semblait approprié, une zone de texte. Je pensais que l’utilisation d’onglets serait un moyen facile de créer la deuxième colonne, mais j’ai découvert que les choses ne fonctionnaient pas très bien.

Il semble y avoir deux problèmes avec la façon dont j'ai essayé de le faire (voir ci-dessous). Tout d'abord, j'ai lu sur de nombreux sites Web que la fonction MeasureString n'était pas très précise en raison de la complexité des polices, des problèmes de crénage, etc. La seconde est que je n'ai aucune idée de ce que le contrôle TextBox utilise en tant que StringFormat en dessous.

Quoi qu'il en soit, le résultat est que je finis toujours par avoir des éléments dans la colonne de droite qui sont désactivés par un onglet. Je suppose que je pourrais ouvrir ma propre fenêtre de texte et tout faire moi-même, mais bon, n'y a-t-il pas un moyen simple de le faire?

    TextBox textBox    = new TextBox();
    textBox.Font       = new Font("Calibri", 11);
    textBox.Dock       = DockStyle.Fill;
    textBox.Multiline  = true;
    textBox.WordWrap   = false;
    textBox.ScrollBars = ScrollBars.Vertical;

    Form form            = new Form();
    form.Text            = "Recipe";
    form.Size            = new Size(400, 600);
    form.FormBorderStyle = FormBorderStyle.Sizable;
    form.StartPosition   = FormStartPosition.CenterScreen;
    form.Controls.Add(textBox);

    Graphics g = form.CreateGraphics();

    float targetWidth = 230;

    foreach (PropertyInfo property in properties)
    {
        string text = String.Format("{0}:\t", Description);

        while (g.MeasureString(text,textBox.Font).Width < targetWidth)
            text += "\t";

        textBox.AppendText(text + value.ToString() + "\n");
    }

    g.Dispose();
    form.ShowDialog();
Était-ce utile?

La solution

Si vous le souhaitez, vous pouvez traduire ce code VB.Net en C #. La théorie est que vous modifiez la taille d'un onglet dans le contrôle.

Private Declare Function SendMessage _
  Lib "user32" Alias "SendMessageA" _
  (ByVal handle As IntPtr, ByVal wMsg As Integer, _
  ByVal wParam As Integer, ByRef lParam As Integer) As Integer


Private Sub SetTabStops(ByVal ctlTextBox As TextBox)

  Const EM_SETTABSTOPS As Integer = &HCBS

  Dim tabs() As Integer = {20, 40, 80}

  SendMessage(ctlTextBox.Handle, EM_SETTABSTOPS, _
    tabs.Length, tabs(0))

End Sub

J'ai également converti une version en C # pour vous. Testé et fonctionnant sous VS2005.

Ajoutez cette instruction using à votre formulaire:

using System.Runtime.InteropServices;

Mettez ceci juste après la déclaration de classe:

    private const int EM_SETTABSTOPS = 0x00CB;
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam);

Appelez cette méthode lorsque vous souhaitez définir les tabulations:

    private void SetTabStops(TextBox ctlTextBox)
    {
        const int EM_SETTABSTOPS = 203;
        int[] tabs = { 100, 40, 80 };
        SendMessage(textBox1.Handle, EM_SETTABSTOPS, tabs.Length, tabs);
    }

Pour l'utiliser, voici tout ce que j'ai fait:

    private void Form1_Load(object sender, EventArgs e)
    {
        SetTabStops(textBox1);

        textBox1.Text = "Hi\tWorld";
    }

Autres conseils

Merci Matt, votre solution a très bien fonctionné pour moi. Voici ma version de votre code ...

// This is a better way to pass in what tab stops I want...
SetTabStops(textBox, new int[] { 12,120 });

// And the code for the SetTabsStops method itself...
private const uint EM_SETTABSTOPS = 0x00CB;

[DllImport("User32.dll")]
private static extern uint SendMessage(IntPtr hWnd, uint wMsg, int wParam, int[] lParam);

public static void SetTabStops(TextBox textBox, int[] tabs)
{
    SendMessage(textBox.Handle, EM_SETTABSTOPS, tabs.Length, tabs);
}

Si vous voulez quelque chose de vraiment tabulaire, la réponse de M. Haren est bonne. DataGridView vous donnera un aspect de type feuille de calcul très Excel.

Si vous souhaitez simplement une disposition en deux colonnes (similaire au tableau HTML), essayez le TableLayoutPanel. Vous obtiendrez la mise en page souhaitée avec la possibilité d’utiliser des contrôles standard dans chaque cellule du tableau.

Je crois que le seul moyen est de faire quelque chose de similaire à ce que vous faites, mais utilisez une police fixe et faites votre propre remplissage avec des espaces afin que vous n'ayez pas à vous soucier de l'expansion des onglets.

Les zones de texte ne permettent-elles pas l'utilisation de HTML? Si tel est le cas, utilisez simplement HTML pour mettre en forme le texte dans un tableau. Sinon, essayez d’ajouter le texte à une grille de données, puis au formulaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top