简体   繁体   中英

Generalizing the form calling in a button event

I usually call this piece of code to show a form whenever a button is clicked.

    private frmSelection _frmSelection;`

    private void _frmSelection_FormClosing(object sender, FormClosingEventArgs e)
    {
        _frmSelection = null;
    }

    private void changeFeedOrderToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (_frmSelection == null)
        {
            _frmSelection = new frmSelection();
            _frmSelection.FormClosing += _frmSelection_FormClosing;
            _frmSelection.WindowState = FormWindowState.Minimized;
            _frmSelection.Show();
            _frmSelection.WindowState = FormWindowState.Normal;
        }
        else
        {
            _frmSelection.WindowState = FormWindowState.Minimized;
            _frmSelection.WindowState = FormWindowState.Normal;
        }
    }

If the form is already open it will show the already opened instance instead of creating new instance. It is working fine.
But my problem is i need to copy paste and change the form name whenever i am adding a new form.
How it can be generalized and added to Helper class?

Something like this:

public sealed class ReusableFormContainer<T> : IDisposable
    where T : Form, new()
{
    private bool isDisposed;

    private void HandleFormClosing(object sender, FormClosingEventArgs e)
    {
        Form = null;
    }

    public T Form { get; private set; }

    public void Show()
    {
        if (isDisposed)
        {
            throw new ObjectDisposedException(null);
        }

        if (Form == null)
        {
            Form = new T { WindowState = FormWindowState.Minimized };
            Form.FormClosing += HandleFormClosing;
            Form.Show();
        }
        else
        {
            Form.WindowState = FormWindowState.Minimized;
        }

        Form.WindowState = FormWindowState.Normal;
    }

    public void Dispose()
    {
        // IDisposable.Dispose is implemented to handle cases, when you want to close
        // wrapped form using code
        if (!isDisposed)
        {
            Form?.Dispose();
            isDisposed = true;
        }
    }
}

Usage:

// must be initialized somewhere in constructors
private readonly ReusableFormContainer<FormA> container_A;
private readonly ReusableFormContainer<FormB> container_B;

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

private void button2_Click(object sender, EventArgs e)
{
    container_B.Show();
}

The following code might do what you want. Just thought about to use the Application functions because those can cover all forms that are on thread.

    public partial class Form1 : Form
{
    public int i; 

    private Form1 _frmSelection;

    public Form1()
    {
        InitializeComponent();
        i = Application.OpenForms.Count;

    }
private void _frmSelection_FormClosing(object sender, FormClosingEventArgs e)
    {
        _frmSelection = null;
    }


    private void button1_Click(object sender, EventArgs e)
    {

        if (_frmSelection == null)
        {

            _frmSelection = new Form1();

            _frmSelection.FormClosing += _frmSelection_FormClosing;
            _frmSelection.WindowState = FormWindowState.Minimized;
            _frmSelection.WindowState = FormWindowState.Normal;
            _frmSelection.Show();

            if (Application.OpenForms.Count > 1)
            {

                _frmSelection.Text = Application.OpenForms[i].Text + " and going";
            }


        }
        else
        {
            _frmSelection.WindowState = FormWindowState.Minimized;
            _frmSelection.WindowState = FormWindowState.Normal;

        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM