1

I have 10 forms and each form has Next and Previous buttons. What is the best approach to show and close forms. I don't need forms to stay in memory. Any ideas?

McDee
  • 142
  • 1
  • 2
  • 10
  • 1
    I would use something other than forms. Why not change the UI to use one form with multiple panels (or something similar)? – webdad3 Jan 12 '12 at 17:38
  • It will then be difficult to read the code. This is huge project. – McDee Jan 12 '12 at 17:40
  • @McDee - The concept you're describing here is generally called a 'Wizard' and their are several good tutorials available that describe proper 'Wizard' implementations. Here is one: http://geekswithblogs.net/jannikanker/archive/2005/03/14/55193.aspx – M.Babcock Jan 12 '12 at 17:41
  • 1
    As an aside, you shouldn't design your GUI based and the percieved readability of the code it will produce. Anyway, you can have non visual classes and theres a thing out there called WPF, might be time to try that on a new project. – Jodrell Jan 12 '12 at 17:45
  • You can make a bunch of user controls and then add and remove user controls as needed – SamFisher83 Jan 12 '12 at 17:47
  • I guess I cannot switch now... have a deadline... got any other ideas? – McDee Jan 12 '12 at 17:57
  • possible duplicate of [Creating Wizards for Windows Forms in C#](http://stackoverflow.com/questions/2340566/creating-wizards-for-windows-forms-in-c-sharp) – Hans Passant Jan 12 '12 at 18:06

3 Answers3

1

I would make use of something similar to a FormSwitcher:

public class FormSwitcher
{
    private List<Func<Form>> constructors;
    private int currentConstructor = 1;

    public FormSwitcher(Func<Form> firstForm)
    {
        constructors = new List<Func<Form>>();
        AddForm(firstForm);
    }

    public void AddForm(Func<Form> constructor)
    {
        constructors.Add(constructor);
    }

    public Form GetNextForm()
    {
        if (constructors.Count > 0 && currentConstructor >= constructors.Count)
        {
            currentConstructor = 0;
        }
        if (constructors.Count > currentConstructor)
        {
            return constructors[currentConstructor++]();
        }
        return null;
    }
}

Your main form should look like this:

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

    private void button1_Click(object sender, EventArgs e)
    {
        new FirstForm().Show();
    }
}

The rotating forms could look like this:

public partial class FirstForm : Form
{
    private FormSwitcher switcher;

    public FirstForm()
    {
        InitializeComponent();
        switcher = new FormSwitcher(() => new FirstForm());
        switcher.AddForm(() => new SecondForm(switcher));
        switcher.AddForm(() => new ThirdForm(switcher));
    }

    private void button1_Click(object sender, EventArgs e)
    {
        switcher.GetNextForm().Show();
        Close();
    }
}

public partial class SecondForm : Form
{
    private FormSwitcher switcher;

    public SecondForm(FormSwitcher switcher)
    {
        InitializeComponent();
        this.switcher = switcher;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        switcher.GetNextForm().Show();
        Close();
    }
}

public partial class ThirdForm : Form
{
    private FormSwitcher switcher;

    public ThirdForm(FormSwitcher switcher)
    {
        InitializeComponent();
        this.switcher = switcher;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        switcher.GetNextForm().Show();
        Close();
    }
}
armen.shimoon
  • 6,303
  • 24
  • 32
1

Don't do it. Have one form, ten user controls, perferably ones that implement an interface.

Take as much of the code out of the forms as you can, all is good... Hit the abstract button now, otherwise next version in you'll be having form 3 check form 1 to see if you can skip form 2 when going back in edge case scenario 634, while rembering if you do go forwrds from 1 you can skip 2 as well, unless they ticked box 14 and put a "Fred" in box 8.

This is not a teeshirt you want to wear.

Tony Hopkinson
  • 20,172
  • 3
  • 31
  • 39
0

I would use a separate reference for each window which you can set to null in case you don't need it any more. When there's no reference any more that points to an object the garbage collector will call it's destructor after some time.

If I got it right you have a number of windows, say n windows, that do their job for some time and are then not needed any more. So when you write

Window myWindow_1 = new Windowd ();
Window myWindow_2 = new Windowd ();
Window myWindow_3 = new Windowd ();
// ...
Window myWindow_n = new Windowd ();

And if you want them to leave the memory you can simply do

myWindow1 = null;
myWindow2 = null;
myWindow3 = null;
//...
myWindow4 = null;

In case these are the only references that were used to link to the Window-objects they will remain as un-referencable ghosts in memory and the garbage collector will remove them after some time.

For simplicity you can hold all these references in an array to avoid giving each object a name. For exapmle:

Window[] myWindows = new Window[n];

for (int i=0; i<n; i++) {

    myWindows[i] = new Window();
}

Hope this helps :)

marc wellman
  • 5,808
  • 5
  • 32
  • 59