Як перевірити, чи вже відкрита форма Windows, та закрити, якщо вона є?


79

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

Як я можу зробити так, що кожні 10 хвилин він перевірятиме, чи відкрита форма "fm" , а якщо відкрита, закриває її та відкриває знову!

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

Мені потрібно мати інструмент для надання йому унікальної ідентичності, а потім перевірити, відкрита ця форма з унікальною ідентичністю чи ні!

Я не хочу просто оновлювати дані у формі (fm), тому що у мене складна інформація з кнопками.

Назва форми - "UpdateWindow"

Дякую


1
Чому ви хочете відкрити його знову? Ви хочете створити новий екземпляр? Я маю на увазі, чому ви не хочете ще раз викликати метод Show?
стандартна локалізація

привіт, вся програма - це внутрішній інструмент нашої компанії, який перевіряє, чи є оновлення для однієї з наших програм, вона працювала нормально, але мені потрібно, щоб її закрити та відкрити знову, тому що вона отримує оновлену інформацію
база даних

2
Чому б вам просто не додати до форми компонент Таймер і не використати таймер для примусового оновлення даних на дисплеї? Ще краще, ви можете прив'язати дані до елементів керування для автоматичного оновлення стану.
Chris Thompson,

2
Я вирішую це за допомогою цього рішення ... Form fc = Application.OpenForms ["UpdateWindow"]; if (fc! = null) fc.Close (); fm.Show (); так що ви думаєте хлопці?
База даних

Оголосити глобальний статичний об'єкт цього типу форми, призначити новоствореному об'єкту цей статичний об'єкт. Після вибуття встановіть для нього значення null. кожного разу, коли ви будете створювати нову форму, спочатку перевірте, чи є статичний об’єкт нульовим чи ні. Це більш компактне рішення, ніж будь-яке інше.
Lali

Відповіді:


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 - це MyForm) {/ * * /}, слід зробити трюк. Але якщо це лише для оновлення, чому б не викликати метод для оновлення даних?
Саша

12
Я вирішую це за допомогою .... Form fc = Application.OpenForms ["UpdateWindow"]; if (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;
}

Сподіваюся, це вирішить проблеми зі створенням декількох екземплярів форми, а також привернення уваги до форми1 за кліком меню, якщо вона вже відкрита або згорнута.


10

Я не впевнений, що розумію твердження. Сподіваюся, це допомагає. Якщо ви хочете оперувати лише одним екземпляром цієї форми, вам слід заборонити Form.Dispose виклик на закритому користувачем. Для цього ви можете обробити закриту подію дочірньої форми.

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();
}

Насправді, я все ще не розумію, чому б вам просто не оновити дані форми.


це цікаво, але як я можу ідентифікувати форму, я маю на увазі, що ми використовуємо форму fm = new form (); отже це завжди нова форма, так як я можу визначити форму?
База даних

Якщо це лише одна така форма, ви можете створити для неї змінну рівня класу. Якщо в купі методів створено багато форм, краще скористайтеся підходом Саші)
локальна установка за замовчуванням

1
Я вирішую це, перевіряючи, чи форма відкрита за іменем, а потім закриваю, якщо вона відкрита. Форма fc = Application.OpenForms ["UpdateWindow"]; if (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) Додайте глобальний var у form.show () і очистіть var у 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

У моєму додатку у мене була форма головного меню, яка мала кнопки для переходу до асортименту інших форм (вони ж під-форми). Я хотів, щоб одночасно працював лише один екземпляр кожної підформи. Плюс я хотів переконатись, якщо користувач намагається запустити вже існуючу підформу, що підформа буде змушена показувати "front & center", якщо вона згорнута або поза вікнами інших програм. Використовуючи найбільш високо оцінені відповіді, я змінив їх відповіді на це:

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();
    }
}

Remenber, щоб додати більше інформації про те, що ви робите у своєму коді
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.