0

I'm not entirely sure this is possible using C# and Windows Forms, but here goes:

I want to split my window into two. On the left is a series of buttons arranged vertically.

On clicking each button, the stuff on the right side has to change. I want different controls displaying for different buttons clicks.

(Kind of like web browser tabs, just on the left pane instead of on top)

I'm guessing I have to use split container, but most of the split container tutorials I've seen have them using the same control on the right, just with different data displaying every time something is clicked.

I hope I'm being clear with what I need. Any help or pointers would be greatly appreciated.

Daje
  • 33
  • 5
  • 3
    Look into [UserControls](http://msdn.microsoft.com/en-us/library/aa302342.aspx) – Mark Hall Nov 07 '13 at 16:28
  • You might want to take a look at [my example](http://stackoverflow.com/questions/18523745/wpf-dynamic-view-content/18539966#18539966) of such a thing using current, relevant .Net Windows Desktop UI features. – Federico Berasategui Nov 07 '13 at 16:38

3 Answers3

0

It is possible and one way is to create new user controls for each of the right-hand interfaces. When you click a button it can load a new instance of one of these controls into the right-hand panel:

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

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

This seems to work when I have tried in the past.

EDIT: As has been pointed out in the comments, this example does not properly dispose of the user controls when cleared! To solve this, call Dispose() prior to clearing the list.

BWHazel
  • 1,474
  • 2
  • 18
  • 31
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.

Alex
  • 23,004
  • 4
  • 39
  • 73
0

The exact layout and the controls you need will be up to you.This is meant as an simplistic starting point to make you see the options you have(here of course 1 option is provided):

1) add splitcontainer to the form.

2) add flowLayoutPanel to left panel of splitcontainer and dock in parent container

3) since you asked for vertical layout set FlowDirection on the flowLayoutPanel to topdown

4) in my example i used 6 buttons and named them(instead could be their text) btncontrol1,2,3...so on, do the same.

5) set all buttons click handler to the same(in this case buttons_Click)

6) copy this code and paste

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

Hope it help you.

terrybozzio
  • 4,424
  • 1
  • 19
  • 25