C # Закрытие определенной формы в мультиформном приложении - PullRequest
4 голосов
/ 23 ноября 2011

Я надеюсь, что вы можете помочь мне с этим. Мое приложение отслеживает базу данных для предупреждений. Когда в базе данных появляется предупреждение, мое приложение добавляет его в основную форму в виде таблицы данных, и в зависимости от его приоритета оно также создает небольшое всплывающее окно winform с событием.

В datagridview есть кнопка, чтобы пометить предупреждение как «увиденное», затем оно обновит базу данных и будет удалено из списка. Однако всплывающая форма для этого события все еще открыта.

Кто-нибудь знает, как закрыть эту форму? Мне нужен способ найти конкретную форму между возможными несколькими открытыми формами оповещений.

Ближайший, который я прошел, это следующий код:

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

Который работает до того момента, пока не закроет правильную форму. затем выдает ошибку: 1010 * «Коллекция была изменена; операция перечисления может не выполняться». Это имеет смысл, но я просто не могу найти другой способ сделать это.

У меня есть класс winform Alert, который создает новые формы. Как вы можете видеть, они получат стандартный текст «Тревога» и уникальное имя на основе идентификатора оповещения.

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

Надеюсь, у кого-нибудь есть хорошие идеи, как мне это сделать. Я искал, но не могу найти простой и элегантный способ сделать это.

Ответы [ 6 ]

4 голосов
/ 23 ноября 2011

Вам нужно добавить разрыв;в вашем цикле после закрытия формы.Коллекция изменяется при закрытии формы (эта форма удаляется из коллекции), что делает цикл foreach недействительным.И не следует ли вам звонить е. Закрыть, а не так. Закрыть?

private void closeForm(int id)

    {
        foreach (Form f in Application.OpenForms)

            if (Convert.ToString(id) == f.Name)
            {
                f.Close();
                break;

            }
    }
4 голосов
/ 23 ноября 2011

Вы должны просто иметь возможность сохранить ссылку на вашу форму в DataGridView или ее DataSource, а затем закрыть форму, используя эту ссылку.Этот подход с меньшей вероятностью сломается в будущем, чем перебор всех форм приложения.

Что, вероятно, будет работать лучше всего, это добавить скрытый столбец к DataGridView, который содержит идентификатор формы, и затем иметьDictionary<int, Form>, который вы используете, чтобы получить ссылку на форму, которую вы хотите закрыть.

Затем вы можете просто получить ссылку на форму из словаря и вызвать close для нее:

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

Кроме того, вы можете хранить Action делегатов вместо ссылок на формы, что позволяет слегка отделить формы оповещений и сетку.

3 голосов
/ 23 ноября 2011

просто получите реф. из foreach цикла и закройте form снаружи.

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();
}
0 голосов
/ 23 ноября 2011
var names = Application.OpenForms.Select(rs=>rs.name).ToList()

foreach (string name in names)
    if (Convert.ToString(id) == name)
    {
        Application.OpenForms[name].Close();
    }
0 голосов
/ 23 ноября 2011

Вы можете использовать тип форм, чтобы найти их (и ToArray, чтобы создать новую коллекцию, избегая изменения коллекции, которую вы перечисляете).

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

В этом случае вам не нужно указывать имя:

Alert alertform = new Alert(id);

alertform.Text = "Alarm";

alertform.Show();
0 голосов
/ 23 ноября 2011

A Close изменяет вашу коллекцию OpenForms, поэтому вместо перечисления по коллекции OpenForms вы можете перечислять по копии.

LINQ очень удобен для создания копий, например:

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

ToList выполняет запрос и сохраняет копию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...