ポップアップ テキスト ウィンドウに 2 つの列を作成する簡単な方法はありますか?

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

質問

これは簡単なことのように思えました。テキスト ウィンドウをポップアップして、2 列のデータ (左側に説明、右側に表示される対応する値) を表示したいだけでした。私はフォームをあまり扱ったことがないので、適切と思われる最初のコントロールである TextBox を取得しただけです。タブを使用すると 2 番目の列を簡単に作成できると思いましたが、うまく機能しないことがわかりました。

私がこれを試みた方法には 2 つの問題があるようです (下記を参照)。まず、フォントが非常に複雑で、カーニングの問題などがあるため、MeasureString 関数はあまり正確ではないということを多くの Web サイトで読みました。2 つ目は、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.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 ステートメントをフォームに追加します。

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

本当に表形式のものが必要な場合は、Mr.ハレンの答えは良いものです。DataGridView は、非常に Excel スプレッドシートのような外観を提供します。

(HTML のテーブルに似た) 2 列のレイアウトが必要なだけの場合は、TableLayoutPanel を試してください。各テーブルセル内で標準コントロールを使用できるため、希望するレイアウトが得られます。

唯一の方法は、あなたがやっていることと同様のことを行うことだと思いますが、固定フォントを使用し、タブの展開を心配する必要がないようにスペースで独自のパディングを行うことです。

テキスト ボックスでは HTML を使用できませんか?その場合は、HTML を使用してテキストを表にフォーマットします。それ以外の場合は、テキストをデータグリッドに追加してから、それをフォームに追加してみてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top