winform shuts down form2 and displays form1

Posted by lettie on Sun, 02 Jan 2022 19:47:52 +0100

winform shuts down form2 and displays form1

Preface

When you are in the water group, you see a high frequency question, which is always asked by many people, so write it simply...

Problem Description

Emerging creates and displays (Show) form2 by clicking on the button in form1 while form1 hides (Hide)

form1 cannot be operated on when form2 is closed, and can only be closed by vs

If non-debugging is used, it is not expected to close

Now you need to show form1 that created form2 while closing form2

Ideas & Solutions (Brief)

1. Simple and rough

The simplest and most rude way to do this is to pass a reference to form1 to form2 through a constructor or some other means while creating form2, and then call form1 inside form2. Show()

Form2.cs

private Form1 form1;
// Pass form1 through a constructor
public Form2(Form1 form)
{
    InitializeComponent();
    form1 = form;
}
// Bind form1 for the closing event of form2. Show() method
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
    form1.Show();
}

Form1.cs

private void OpenForm2_Click(object sender, EventArgs e)
{
    // Pass form1 when creating form2
    var form2 = new Form2(this);
    form2.Show();
    Hide();
}

This basically fulfills the above requirements, and if form2 may have multiple creators, simply change the Form1 saved in form2 to Form

Form2.cs

private Form Creator;
// Pass form1 through a constructor
public Form2(Form form)
{
    InitializeComponent();
    Creator = form;
}
// Bind form1 for the closing event of form2. Show() method
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
    Creator.Show();
}

Using the base class Form for all forms can simplify many operations

2. Use built-in events

Microsoft Form has some built-in events that we can use to fulfill these needs

The FormClosed event is triggered when the Form form is closed, adding a delegate to the event is sufficient

Form1.cs

private void OpenForm2_Click(object sender, EventArgs e)
{
    var form2 = new Form2();
    // If you just need to fulfill the above requirements, discard the dollar
    form2.FormClosed += (_, _) => Show();
    form2.Show();
    Hide();
}

Form2 does not require any changes

A more troublesome method

3. Custom Events/Delegates

Using built-in events can meet basic needs, but if you need to pass data to From1, it may not be enough

You can customize events or delegates at this time

Form2.cs

public Form4()
{
    InitializeComponent();
}
// Pass an int-type value
public EventHandler<int> EventWithInt;
// Pass a value of type DateTime
public Action<DateTime> FuncWithTime;

private void ToggleEvent_Click(object sender, EventArgs e)
{
    EventWithInt(sender, 233);
}

private void ToggleFunc_Click(object sender, EventArgs e)
{
    FuncWithTime(DateTime.Now);
}

Form2 defines an event EventHandler <int> EventWithInt and a delegate Action <DateTime> FuncWithTime, which are triggered when the button is clicked

Form1.cs

private void OpenForm2_Click(object sender, EventArgs e)
{
    var form2 = new Form2();
    form2.EventWithInt += (_, num) => OpenForm2.Text = num.ToString();
    form2.FuncWithTime += time => OpenForm2.Text = time.ToString();
    form2.Show();
}

Bind the corresponding delegate when Form2 is created in Form1 and modify the Text property of the button in Form1 when Form2 is clicked

4. Encapsulation of "do more than one thing"

Occasionally Form1 creates Form2, then Form2 creates Form3, then Form3...

By the time Form233 arrives, you may need Form1.Show(), in which case all of the above solutions may work, but implementation is too cumbersome or can result in very large intrusions into all Forms on the path

So here's a "very simple" idea

public class SimpleQueue
{
    // It may be better to use a dictionary or other collection type
    private static List<Action<string>> Events = new();

    public static void Reg(Action<string> action)
    {
        Events.Add(action);
    }
    public static void Send(string msg)
    {
        Events.ForEach(item => item(msg));
    }
}

Form1.cs

public Form1()
{
    InitializeComponent();
    SimpleQueue.Reg(item =>
        {
            if (item is "ShowForm1") Show();
            if (item == "HideForm1") Hide();
        }
    );
}

Form233.cs

private void Form233_FormClosed(object sender, FormClosedEventArgs e)
{
    SimpleQueue.Send("ShowForm1");
}

This will roughly meet the needs, but there are still many issues to solve and there is interest in expanding

Events may be better with dictionaries or other collection types, but it's not worth it just for a simple demonstration

I guess it's probably a duplicate wheel

Topics: winform DotNet