As the question is about WinForms and I don't want to, well.. go against convention and answer with a suggestion for you to use a different technology right away I will answer the question normally first and provide afterthoughts under on what I suggest you actually do. Whatever anyone says, never use MDI for this. It is not intended for this and will just baffle your users. So here it goes, a small view based controller framework with a minimalistic approach.
First the host form's interface (IHost.cs):
public interface IHost
{
/// <summary>
/// Destroys the current view and creates a new from name
/// </summary>
/// <param name="name">The name of the view you wish to start</param>
void SwitchView(string name);
View CurrentView { get; }
}
Then, the views interface. Now, visual studio will tell you this is a UserControl in the design. Mistake not! It is, but should not be used as one. Never actually put stuff on that designer, should you do remove the classes it creates on the right hand side. This is a base for all views, if you edit this all views will have that part of the interface.
(View.cs)
using System.Windows.Forms; //Above your namespace
public class View : UserControl
{
/// <summary>
/// Warning! Attempting to use this constructor and host (eg switching views)
/// will result in exceptions unless host is manually set
/// </summary>
protected View()
{
}
protected View(IHost host)
{
Host = host;
}
public virtual IHost Host { get; }
}
Now the host form looks like this (HostForm.cs, this is my entry point and the thing I show the main user):
using System.Collections.Generic; //Above your namespace
using System.Windows.Forms; //Above your namespace
public partial class HostForm : Form, IHost
{
public View CurrentView { get; private set; }
public HostForm()
{
InitializeComponent();
SwitchView("UserLabel");
}
public void SwitchView(string name)
{
Controls.Remove(CurrentView);
CurrentView = CreateViewFromName(name);
Controls.Add(CurrentView);
CurrentView.Show();
}
private View CreateViewFromName(string name)
{
switch (name.ToLowerInvariant())
{
case "userlabel":
return new UserLabel(this);
case "usertext":
return new UserText(this);
}
throw new KeyNotFoundException("Could not find a form with that name!");
}
}
From here on, create a normal UserControl but in the cs code change "UserControl" to View and in your host form add a name conversion for it like you've seen above. Here are two views I created (design omitted)
(UserLabel.cs)
public partial class UserLabel : View
{
public UserLabel(IHost host) : base(host)
{
InitializeComponent();
}
private void SubmitButton_Click(object sender, System.EventArgs e)
{
Host.SwitchView("UserText");
}
}
(UserText.cs)
public partial class UserText : View
{
public UserText(IHost host) : base(host)
{
InitializeComponent();
}
private void LoginButton_Click(object sender, EventArgs e)
{
Host.SwitchView("UserLabel");
}
}
Feel free to ask questions on this design in the comment section.
Now as for what I actually recommend? If you need windows desktop applications, and don't want to target the universal app framework I recommend WPF. Both Wikipedia and Microsoft Developer Network(MSDN) have great instructions on how to get started. As for pattern I recommend you use MVVM and move on from there. Lots of resources are available online.