有没有一种简单的方法可以在弹出文本窗口中创建两列?

时间:2020-03-05 18:55:55  来源:igfitidea点击:

这似乎是一件容易的事。我只是想弹出一个文本窗口并显示两列数据-左侧的描述和右侧显示的对应值。我没有使用Forms太多,所以我只抓住了第一个看似合适的控件,即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();

解决方案

回答

文本框是否允许使用HTML?如果是这种情况,只需使用HTML将文本格式设置为表格即可。否则,请尝试将文本添加到数据网格,然后将其添加到表单。

回答

如果需要,可以将此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

我也将版本转换为Cfor。经过测试并在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";
    }

回答

如果我们想要某种真正的表格形式,哈伦先生的答案就是一个很好的答案。 DataGridView将为我们提供非常出色的Excel电子表格类型的外观。

如果只需要两列布局(类似于HTML的表),请尝试使用TableLayoutPanel。它可以为我们提供所需的布局,并可以在每个表单元格中使用标准控件。

回答

我相信唯一的方法是执行与我们正在执行的操作类似的操作,但是使用固定字体并使用空格进行自己的填充,以使我们不必担心制表符扩展。

回答

谢谢Matt,解决方案对我来说非常有用。这是我的代码版本...

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