C # Closing a specific form in a diverse application

I hope you help me with this. My application controls the database for alerts. When a warning appears in the database, my application will add it to the main form in the datagridview, and depending on its priority, it will also create a small winform popup with an event.

There is a button in datagridview to mark the warning as "seen", then it will update the database and whether it will be removed from the list. However, the pop-up form for this event is still open.

Does anyone know how to close this form? I need a way to find a specific form between possible open forms of a firewall.

The closest I came to is the following code:

private void closeForm(int id) { foreach (Form f in Application.OpenForms) { if (Convert.ToString(id) == f.Name) { this.Close(); } } } 

This works until it closes the correct form. then it gives an error message: "The collection has been changed, the enumeration operation may not be performed." This view makes sense, but I just can't figure out how to do it.

I have a winform class called Alert that creates new forms. As you can see, they will receive the standard text β€œAlarm” and a unique name based on the alert identifier.

 Alert alertform = new Alert(id); alertform.Name = formid; alertform.Text = "Alarm"; alertform.Show(); 

Hope someone has some good ideas on how I can do this. I searched, but cannot find a simple and elegant way to do this.

+4
source share
6 answers

You need to add break; into your loop after closing the form. The collection is modified when the form is closed (this form is removed from the collection), which makes the foreach loop invalid. And shouldn't you call f.Close, not this.Close?

 private void closeForm(int id) { foreach (Form f in Application.OpenForms) if (Convert.ToString(id) == f.Name) { f.Close(); break; } } 
+4
source

You just need to save the link to your form in the DataGridView or its DataSource , and then close the form using this link. This approach is less likely to be violated in the future than the repetition of all application forms.

What works best is to add a hidden column to the DataGridView that contains the form identifier, and also have a Dictionary<int, Form> that you use to get a link to the form you want to close.

Then you can simply get the link to the form from the dictionary and close it:

 private void CloseAlertForm(int id) { Form f = dict[id]; f.Close(); dict.Remove(id); } 

In addition, you can store Action delegates instead of links to the form, which allows you to slightly separate the notification forms and the grid form.

+4
source

just get ref. out of the foreach and close the form outside of it.

 private void closeForm(int id) { Form formtoclose=null; foreach (Form f in Application.OpenForms) { if (Convert.ToString(id) == f.Name) { formtoclose = f; } } if(formtoclose!=null) formtoclose.Close(); } 
+3
source

A Close modifies your OpenForms collection, so instead of listing through the OpenForms collection, you can list a copy.

LINQ is very convenient for creating copies, for example:

 foreach (Form f in Application.OpenForms.Where(i => Convert.ToString(id) == i.Name).ToList()) { // Save to close the form here } 

ToList executes the request and saves a copy.

-1
source

You can use the type of forms to search for them (And ToArray to create a new collection to avoid changing the collection you are listing).

 private void CloseAlerts() { var openForms = Application.OpenForms.Cast<Form>(); foreach (var f in openForms.Where(f => f is Alert).ToArray()) { f.Close(); } } 

In this case, you do not need to specify a name:

 Alert alertform = new Alert(id); alertform.Text = "Alarm"; alertform.Show(); 
-2
source
 var names = Application.OpenForms.Select(rs=>rs.name).ToList() foreach (string name in names) if (Convert.ToString(id) == name) { Application.OpenForms[name].Close(); } 
-2
source

Source: https://habr.com/ru/post/1382685/


All Articles