Есть ли простой способ создать два столбца во всплывающем текстовом окне?
-
09-06-2019 - |
Вопрос
Это казалось легким делом.Я просто хотел открыть текстовое окно и отобразить два столбца данных - описание с левой стороны и соответствующее значение, отображаемое с правой стороны.Я не очень много работал с формами, поэтому просто взял первый элемент управления, который показался подходящим, текстовое поле.Я думал, что использование вкладок было бы простым способом создать второй столбец, но я обнаружил, что все работает не так хорошо.
Кажется, есть две проблемы с тем, как я пытался это сделать (см. Ниже).Во-первых, я читал на многочисленных веб-сайтах, что функция 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, а затем добавить его в форму.