0

我不完全确定这是否可以使用 C# 和 Windows 窗体,但这里有:

我想把我的窗口一分为二。左侧是一系列垂直排列的按钮。

单击每个按钮时,右侧的内容必须更改。我希望为不同的按钮点击显示不同的控件。

(有点像网络浏览器选项卡,只是在左窗格而不是在顶部)

我猜我必须使用拆分容器,但我见过的大多数拆分容器教程都使用右侧的相同控件,只是每次单击某些内容时显示不同的数据。

我希望我清楚我需要什么。任何帮助或指示将不胜感激。

4

3 回答 3

0

You can get the job done with a TabControl, as explained on MSDN. It shows an example on how to put the tabs on the right side but switching "right" with "left" should provide the behavior you seek.

I tried it in a WinForms app and it seems to work fine, despite the ugly colors used in the example... The following takes ~30 secs to implement.

Quoting from the link:

To display right-aligned tabs

  1. Add a TabControl to your form.
  2. Set the Alignment property to Right. if you set Left it goes on the left no problem
  3. Set the SizeMode property to Fixed, so that all tabs are the same width.
  4. Set the ItemSize property to the preferred fixed size for the tabs. Keep in mind that the ItemSize property behaves as though the tabs were on top, although they are right-aligned. As a result, in order to make the tabs wider, you must change the Height property, and in order to make them taller, you must change the Width property.
  5. Set the DrawMode property to OwnerDrawFixed.
  6. Define a handler for the DrawItem event of TabControl that renders the text from left to right.

And this is the code (converted to C# since MSDN only shows VB):

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    Graphics g = e.Graphics;
    Brush _TextBrush = default(Brush);

    // Get the item from the collection. 
    TabPage _TabPage = tabControl1.TabPages[e.Index];

    // Get the real bounds for the tab rectangle. 
    Rectangle _TabBounds = tabControl1.GetTabRect(e.Index);

    if ((e.State == DrawItemState.Selected))
    {
        // Draw a different background color, and don't paint a focus rectangle.
        _TextBrush = new SolidBrush(Color.Red);
        g.FillRectangle(Brushes.Gray, e.Bounds);
    }
    else
    {
        _TextBrush = new System.Drawing.SolidBrush(e.ForeColor);
        e.DrawBackground();
    }

    // Use our own font. 
    Font _TabFont = new Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Pixel);

    // Draw string. Center the text. 
    StringFormat _StringFlags = new StringFormat();
    _StringFlags.Alignment = StringAlignment.Center;
    _StringFlags.LineAlignment = StringAlignment.Center;
    g.DrawString(_TabPage.Text, _TabFont, _TextBrush, _TabBounds, new StringFormat(_StringFlags));
}

Just put your content in the TabControl and you're (sorta) good to go.

于 2013-11-07T16:44:55.620 回答
0

您需要的确切布局和控件将取决于您。这是一个简单的起点,让您看到您拥有的选项(这里当然提供了 1 个选项):

1)将拆分容器添加到表单中。

2)将flowLayoutPanel添加到splitcontainer的左面板并停靠在父容器中

3)由于您要求将 flowLayoutPanel 上的垂直布局设置 FlowDirection 为自上而下

4) 在我的示例中,我使用了 6 个按钮并将它们命名(而不是它们的文本)btncontrol1,2,3...等等,做同样的事情。

5)将所有按钮单击处理程序设置为相同(在本例中为buttons_Click)

6)复制此代码并粘贴

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void buttons_Click(object sender, EventArgs e)
        {
            Button b = sender as Button;

            switch (b.Name)
            {
                //of course after each ClearPanel what i do is only for
                //demonstration.
                case "btnControl1":
                    splitContainer1.Panel2.SuspendLayout();
                    ClearPanel();
                    splitContainer1.Panel2.Controls.Add(new ListBox());
                    splitContainer1.Panel2.ResumeLayout();
                    break;
                case "btnControl2":
                    splitContainer1.Panel2.SuspendLayout();
                    ClearPanel();
                    splitContainer1.Panel2.Controls.Add(new RadioButton());
                    splitContainer1.Panel2.ResumeLayout();
                    break;
                case "btnControl3":
                    splitContainer1.Panel2.SuspendLayout();
                    ClearPanel();
                    splitContainer1.Panel2.Controls.Add(new Button());
                    splitContainer1.Panel2.ResumeLayout();
                    break;
                case "btnControl4":
                    splitContainer1.Panel2.SuspendLayout();
                    ClearPanel();
                    splitContainer1.Panel2.Controls.Add(new DateTimePicker());
                    splitContainer1.Panel2.ResumeLayout();
                    break;
                case "btnControl5":
                    splitContainer1.Panel2.SuspendLayout();
                    ClearPanel();
                    splitContainer1.Panel2.Controls.Add(new DataGridView());
                    splitContainer1.Panel2.ResumeLayout();
                    break;
                case "btnControl6":
                    splitContainer1.Panel2.SuspendLayout();
                    ClearPanel();
                    splitContainer1.Panel2.Controls.Add(new TextBox());
                    splitContainer1.Panel2.ResumeLayout();
                    break;
                default:
                    break;
            }
        }

        private void ClearPanel()
        {
            if (splitContainer1.Panel2.HasChildren)
            {
                foreach (Control c in splitContainer1.Panel2.Controls)
                {
                    c.Dispose();
                }
                splitContainer1.Panel2.Controls.Clear();
            }
        }
    }

希望对您有所帮助。

于 2013-11-07T17:39:29.873 回答
0

这是可能的,一种方法是为每个右侧界面创建新的用户控件。当您单击一个按钮时,它可以将这些控件之一的新实例加载到右侧面板中:

if (splitContainer.Panel2.Controls.Count > 0)
{
    splitContainer.Panel2.Controls[0].Dispose();    // Edit
    splitContainer.Panel2.Controls.Clear();
}

splitContainer.Panel2.Controls.Add(new RightHandControl());

当我过去尝试过时,这似乎有效。

编辑:正如评论中所指出的,这个例子在清除时没有正确处理用户控件!要解决此问题,请Dispose()在清除列表之前致电。

于 2013-11-07T16:42:00.937 回答