Как проверить, открыта ли уже форма окна, и закрыть ее, если она есть?


79

У меня есть форма "fm", которая представляет собой простое информационное окно, которое открывается каждые 10 минут ( fm.Show();).

Как я могу сделать это каждые 10 минут, он будет проверять, открыта ли форма "fm", и если она открыта, то закрывает ее и открывает снова!

Теперь форма fm всегда создается с помощью, form fm = new form();
поэтому, когда я пытаюсь проверить, открыта ли форма, она всегда будет ложной и откроет новое окно, даже если раньше была одна форма!

Мне нужен инструмент, чтобы придать ему уникальную идентичность, а затем проверить, открыта ли эта форма с уникальной идентичностью или нет!

Я не хочу просто обновлять данные в форме (fm), потому что у меня сложная информация с кнопками.

Имя формы "UpdateWindow"

благодаря


1
Почему ты хочешь снова его открыть? Вы хотите создать новый экземпляр? Я имею в виду, почему бы вам не вызвать метод Show еще раз?
локаль по умолчанию

привет, вся программа - это внутренний инструмент в нашей компании, который проверяет, есть ли обновление для одной из наших программ, он работал нормально, но мне нужно его закрыть и снова открыть, потому что он получает обновленную информацию
Data-Base

2
Почему бы вам просто не добавить компонент Timer в форму и не использовать таймер для принудительного обновления данных на дисплее? Более того, вы можете привязать элементы управления к объекту для автоматического обновления статуса.
Крис Томпсон

2
Решаю этим решением ... Форма fc = Application.OpenForms ["UpdateWindow"]; если (fc! = null) fc.Close (); fm.Show (); так что вы думаете, ребята?
База данных

Объявите глобальный статический объект этого типа формы, назначьте вновь созданный объект этому статическому объекту. При удалении установите для него значение null. каждый раз, когда вы будете создавать новую форму, сначала проверяйте, является ли статический объект нулевым или нет. Это более компактное решение, чем любое другое.
Лали

Ответы:


92

возможно, это поможет:

FormCollection fc = Application.OpenForms;

foreach (Form frm in fc)
{
//iterate through
     if (frm.Name == "YourFormName")
     {
         bFormNameOpen = true;
     }
}

Некоторый код в foreach для определения конкретной формы, и это можно сделать. Однако непроверенный.

Найдено на http://bytes.com/topic/c-sharp/answers/591308-iterating-all-open-forms


Спасибо, а как использовать его с моей формой (FM)?
База данных

if (frm is MyForm) {/ * * /}, должно помочь. Но если это просто обновление, почему бы не вызвать метод для обновления данных?
Саша

12
Решаю вот этим .... Форма fc = Application.OpenForms ["UpdateWindow"]; если (fc! = null) fc.Close (); fm.Show ();
База данных

1
Я получил эту ошибку после закрытия формы с ней: System.InvalidOperationException: 'Коллекция была изменена; операция перечисления может не выполняться. '
noobsee

45

Я знаю, что опаздываю ... Но для любопытных ... Это другой способ

if (Application.OpenForms.OfType<UpdateWindow>().Count() == 1)
    Application.OpenForms.OfType<UpdateWindow>().First().Close();

UpdateWindow frm = new UpdateWindow()
frm.Show();

Намного лучшее использование фреймворка, чем принятый ответ imho.
Gaspa79

14

Предположим, что если мы вызываем форму из меню, щелкнув по форме MDI, то нам нужно создать объявление экземпляра этой формы на верхнем уровне следующим образом:

Form1 fm = null;

Затем нам нужно определить событие щелчка меню для вызова Form1 следующим образом:

private void form1ToolStripMenuItem_Click(object sender, EventArgs e)
{
    if (fm == null|| fm.Text=="")
    {
        fm = new Form1();              
        fm.MdiParent = this;
        fm.Dock = DockStyle.Fill;
        fm.Show();
    }
    else if (CheckOpened(fm.Text))
    {
        fm.WindowState = FormWindowState.Normal;
        fm.Dock = DockStyle.Fill;
        fm.Show();
        fm.Focus();               
    }                   
}

CheckOpened определяется для проверки Form1 уже открыт или нет:

private bool CheckOpened(string name)
{
    FormCollection fc = Application.OpenForms;

    foreach (Form frm in fc)
    {
        if (frm.Text == name)
        {
            return true; 
        }
    }
    return false;
}

Надеюсь, это решит проблемы с созданием нескольких экземпляров формы, а также переключением внимания на форму Form1 при нажатии на меню, если она уже открыта или свернута.


10

Я не уверен, что понимаю это утверждение. Надеюсь это поможет. Если вы хотите работать только с одним экземпляром этой формы, вам следует запретить вызов Form.Dispose при закрытии пользователя. Для этого вы можете обработать событие Closing дочерней формы.

private void ChildForm_FormClosing(object sender, FormClosingEventArgs e)
{
    this.Hide();
    e.Cancel = true;
}

И тогда вам не нужно создавать новые экземпляры frm. Просто вызовите метод Show на экземпляре.

Вы можете проверить свойство Form.Visible, чтобы проверить, открыта ли форма в данный момент.

private ChildForm form = new ChildForm();

private void ReopenChildForm()
{
    if(form.Visible)
    {
        form.Hide();
    }
    //Update form information
    form.Show();
}

На самом деле, я до сих пор не понимаю, почему бы вам просто не обновить данные в форме.


это интересно, но как я могу идентифицировать форму, я имею в виду, что мы используем form fm = new form (); так что это всегда новая форма, так как я могу идентифицировать форму?
База данных

Если это только одна такая форма, вы можете создать для нее переменную уровня класса. Если существует множество форм, созданных с помощью набора методов, вам лучше использовать подход Sascha)
локаль по умолчанию

1
Я решаю эту проблему, проверяя, открыта ли форма по имени, а затем закрываю ее, если она открыта Form fc = Application.OpenForms ["UpdateWindow"]; если (fc! = null) fc.Close (); fm.Show ();
База данных


2
Form1 fc = Application.OpenForms["Form1 "] != null ? (Form1 ) Application.OpenForms["Form1 "] : null;
if (fc != null)
{
    fc.Close();
}

Он закроет форму1, вы можете снова открыть эту форму, если хотите, используя:

Form1 frm = New Form1();
frm.show();

1
if( ((Form1)Application.OpenForms["Form1"]).Visible == true)
    //form is visible
else
    //form is invisible

где Form1имя вашей формы.


1

Попробуйте, это сработает:

//inside main class
Form1 Fm1 = new Form1();<br>

//in button click
if (Fm1.IsDisposed)
{
    Fm1 = new Form();
}
Fm1.Show();
Fm1.BringToFront();
Fm1.Activate();


1

попробуйте эту функцию MDICHILD

public void mdiChild(Form mdiParent, Form mdiChild)
{
    foreach (Form frm in mdiParent.MdiChildren)
    {
        // check if name equals
        if (frm.Name == mdiChild.Name)
        {
            //close if found

            frm.Close();

            return;
        }
    }

    mdiChild.MdiParent = mdiParent;

    mdiChild.Show();

    mdiChild.BringToFront();
}

0

Попробуйте подключить ниже,

private void frmMyForm_Deactivate(object sender, EventArgs e)
    {
        // Raise your flag here.
    }

Подключив указанное выше событие, он сообщит вам, когда форма свернута или частично / полностью скрыта другой формой.


0

Это то, что я использовал для закрытия всех открытых форм (кроме основной формы)

    private void CloseOpenForms()
    {

           // Close all open forms - except for the main form.  (This is usually OpenForms[0].
           // Closing a form decrmements the OpenForms count
           while (Application.OpenForms.Count > 1)
           {
               Application.OpenForms[Application.OpenForms.Count-1].Close();
           }
    }

0

Забавно, пришлось добавить в эту ветку.

1) Добавьте глобальную переменную в form.show () и очистите переменную в form.close ()

2) В родительской форме добавьте таймер. Держите дочернюю форму открытой и обновляйте свои данные каждые 10 минут.

3) поместите таймер в дочернюю форму, чтобы обновить данные о себе.


0

* Надеюсь, это сработает для вас

System.Windows.Forms.Form f1 = System.Windows.Forms.Application.OpenForms["Order"];
if(((Order)f1)!=null)
{
//open Form
}
else
{
//not open
}

0

попробуй это

 bool IsOpen = false;
    foreach (Form f in Application.OpenForms)
    {
        if (f.Text == "Form2")
        {
            IsOpen = true;
            f.Focus();
            break;
        }
    }

    if (IsOpen == false)
    {
        Form2 f2 = new Form2();
        f2.MdiParent = this;
        f2.Show();
    }

0
 private static Form IsFormAlreadyOpen(Type formType)
 {
     return Application.OpenForms.Cast<Form>().FirstOrDefault(openForm => openForm.GetType() == formType);
 }

Хотя этот фрагмент кода может решить вопрос, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода. Также постарайтесь не загромождать свой код пояснительными комментариями, так как это снижает удобочитаемость как кода, так и пояснений!
Прощай, StackExchange

0

Форма только один раз

Если ваша цель - вызвать несколько экземпляров формы, подумайте о следующем ...

public class MyForm : Form
{
    private static MyForm alreadyOpened = null;

    public MyForm()
    {
        // If the form already exists, and has not been closed
        if (alreadyOpened != null && !alreadyOpened.IsDisposed)
        {
            alreadyOpened.Focus();            // Bring the old one to top
            Shown += (s, e) => this.Close();  // and destroy the new one.
            return;
        }           

        // Otherwise store this one as reference
        alreadyOpened = this;  

        // Initialization
        InitializeComponent();
    }
}

0
Form user_rpt = Application.OpenForms["frmUesr_reports"];
        if (user_rpt == null)
        {
            /// Do Something here
        }

Попробуйте это Это краткая идея, чтобы проверить, открыта ли форма


0

В моем приложении у меня была форма главного меню, в которой были кнопки для перехода к ассортименту других форм (также известных как подформы). Я хотел, чтобы одновременно выполнялся только один экземпляр каждой подформы. Кроме того, я хотел убедиться, что если пользователь попытается запустить уже существующую подформу, подформа будет вынуждена отображать «переднюю и центральную часть», если она свернута или находится позади окон других приложений. Используя самые популярные на данный момент ответы, я реорганизовал их ответы следующим образом:

private void btnOpenSubForm_Click(object sender, EventArgs e)
    {

        Form fsf = Application.OpenForms["formSubForm"];

        if (fsf != null)
        {
            fsf.WindowState = FormWindowState.Normal;
            fsf.Show();
            fsf.TopMost = true;
        }
        else
        {
            Form formSubForm = new FormSubForm();
            formSubForm.Show();
            formSubForm.TopMost = true;
        }
    }

0

Это сработало у меня:

public void DetectOpenedForm()
{
    FormCollection AllForms = Application.OpenForms;
    Boolean FormOpen = false;
    Form OpenedForm = new Form();
    foreach (Form form in AllForms)
    {
        if (form.Name == "YourFormName")
        {
            OpenedForm = form;
            FormOpen = true;
        }
    }
    if (FormOpen == true)
    {
        OpenedForm.Close();
    }
}

Ременбер, чтобы добавить дополнительную информацию о том, что вы делаете в своем коде
xsami

0

Думаю, мой способ самый простой .

    Form2 form2 = null;
    private void SwitchFormShowClose_Click(object sender, EventArgs e)
    {  
        if(form2 == null){
            form2 = new Form2();
            form2.Show();
        }
        else{
            form2.Close();
            form2 = null;
        }
    }

0

Ниже на самом деле работает очень хорошо.

private void networkInformationToolStripMenuItem_Click(object sender, EventArgs e)
{
    var _open = false;
    FormCollection fc = Application.OpenForms;
    foreach (Form frm in fc)
    {
        if (frm.Name == "FormBrowseNetworkInformation")
        {
            _open = true;
            frm.Select();
            break;
        }
    }
    if (_open == false)
    {
        var formBrowseNetworkInformation = new FormBrowseNetworkInformation();
        formBrowseNetworkInformation.Show();
    }
}

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

0

это будет слово определенно. Я использую эту функцию и для себя.

  public static bool isFormOpen(Form formm)
    {

        foreach (Form OpenForm in Application.OpenForms)
        {
            if (OpenForm.Name == formm.Name)
            {
                return true;
            }
        }

        return false;
    }

0

Я подправил предыдущий пост. Это работает безупречно, без необходимости повторять все открытые формы.

        Form fc = Application.OpenForms["FormBrowse"];
        if (fc != null)
        {
            fc.Select();
        }
        else
        {
            var formBrowse = new FormBrowse();
            formBrowse.Show();
        }

0

попробуйте это, не нужно перебирать формы:

if(Application.OpenForms["<your_form_name>"] != null){

   //Your form is already open

}
else {

  //Your form isn't open

}

0

Это работает, если вы хотите проверить, открыта ли уже вторая форма, и не открывать ее снова нажатием кнопки.

 int formcheck = 0;
    private void button_click()
    {
       Form2Name myForm2 = new Form2Name();
       if(formcheck == 0)
       {
          myForm2.Show(); //Open Form2 only if its not active and formcheck == 0
          // Do Somethin

          formcheck = 1; //Set it to 1 indicating that Form2 have been opened
       {   
    {

-1

Вдобавок может это поможет


class Helper
    {
        public void disableMultiWindow(Form MdiParent, string formName)
        {
            FormCollection fc = Application.OpenForms;
            try
            {
                foreach (Form form in Application.OpenForms)
                {
                    if (form.Name == formName)
                    {
                        form.BringToFront();
                        return;
                    }
                }

                Assembly thisAssembly = Assembly.GetExecutingAssembly();
                Type typeToCreate = thisAssembly.GetTypes().Where(t => t.Name == formName).First();
                Form myProgram = (Form)Activator.CreateInstance(typeToCreate);
                myProgram.MdiParent = MdiParent;
                myProgram.Show();
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }
    }

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.