Есть ли простой способ создать два столбца во всплывающем текстовом окне?

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

Вопрос

Это казалось легким делом.Я просто хотел открыть текстовое окно и отобразить два столбца данных - описание с левой стороны и соответствующее значение, отображаемое с правой стороны.Я не очень много работал с формами, поэтому просто взял первый элемент управления, который показался подходящим, текстовое поле.Я думал, что использование вкладок было бы простым способом создать второй столбец, но я обнаружил, что все работает не так хорошо.

Кажется, есть две проблемы с тем, как я пытался это сделать (см. Ниже).Во-первых, я читал на многочисленных веб-сайтах, что функция MeasureString не очень точна из-за сложности шрифтов, проблем с кернингом и всего остального.Во-вторых, я понятия не имею, что элемент управления TextBox использует в качестве своего StringFormat внизу.

В любом случае, в результате я неизменно получаю элементы в правом столбце, которые отключены табуляцией.Я полагаю, я мог бы открыть свое собственное текстовое окно и сделать все сам, но боже, неужели нет простого способа сделать это?

    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();
Это было полезно?

Решение

Если вы хотите, вы можете перевести этот VB.Чистый код на C #.Теория здесь заключается в том, что вы изменяете размер вкладки в элементе управления.

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

Я тоже преобразовал версию на C # для вас.Протестирован и работает в VS2005.

Добавьте это заявление using в свою форму:

using System.Runtime.InteropServices;

Поместите это сразу после объявления класса:

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

Вызовите этот метод, когда вы хотите установить вкладки:

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

Чтобы использовать это, вот все, что я сделал:

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

        textBox1.Text = "Hi\tWorld";
    }

Другие советы

Спасибо, Мэтт, ваше решение отлично сработало для меня.Вот моя версия вашего кода...

// 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);
}

Если вам нужно что-то по-настоящему табличное, мистерОтвет Харена - хороший.DataGridView придаст вам вид, очень похожий на электронную таблицу Excel.

Если вам просто нужен макет из двух столбцов (аналогичный таблице HTML), попробуйте TableLayoutPanel.Это даст вам желаемый макет с возможностью использования стандартных элементов управления в каждой ячейке таблицы.

Я считаю, что единственный способ - это сделать что-то похожее на то, что делаете вы, но использовать фиксированный шрифт и делать свои собственные отступы с пробелами, чтобы вам не приходилось беспокоиться о расширении табуляции.

Разве текстовые поля не допускают использование HTML?Если это так, просто используйте HTML для форматирования текста в таблицу.В противном случае попробуйте добавить текст в datagrid, а затем добавить его в форму.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top