2008-09-16 3 views
1

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

Кажется, есть две проблемы с тем, как я пытался это сделать (см. Ниже). Во-первых, я читал на многочисленных веб-сайтах, что функция 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(); 

ответ

0

Если вы хотите, вы можете перевести этот код VB.Net на 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 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"; 
    } 
-2

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

0

Если вы хотите что-то действительно табличное, то ответ г-на Харена хороший. DataGridView предоставит вам вид Excel в виде таблицы Excel.

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

-1

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

+0

Да, фиксированный шрифт также решит проблему, но фиксированные шрифты имеют тенденцию выглядеть скорее UGLY, так что это не было хорошим решением для меня. – AZDean 2008-09-16 14:11:05

+0

Ничего себе, отмеченный ASK'er вопроса, основанный на эстетике шрифта !! – bruceatk 2008-10-01 21:27:20

1

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

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