Aman Susanto Ответов: 2

как предотвратить повторное открытие формы


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

это мой код. :
ToolStripMenuItem SubMenu = new ToolStripMenuItem(sdr1["description"].ToString(), null, new EventHandler(klikMenu));

private void klikMenu(object sender, EventArgs e)
        {
            string sFormName = "AIO_System." + ((ToolStripMenuItem)sender).Tag.ToString();
            System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();

            Form frm = (Form)asm.CreateInstance(sFormName);    <======
            if(!IsFormOpen(frm.GetType()))
                {
                    frm.Owner = this;
                    frm.Show();
                }
                else
                    frm.Focus();
            }
        }

        private bool IsFormOpen(Type formType)
        {
            foreach (Form form in Application.OpenForms)
                if (form.GetType().Name == form.Name)
                    return true;
            return false;
        }

BillWoodruff

Это репост вопроса заданного за 11 часов до этого поста который имел несколько полезных ответов:

http://www.codeproject.com/Messages/4765814/how-to-prevent-form-open-twice.aspx

2 Ответов

Рейтинг:
4

bling

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


частная klikMenu недействительным(объект отправителя, EventArgs в электронной)
{
строка sFormName = "AIO_System." + ((ToolStripMenuItem)sender).Tag.ToString();
Система.Отражение.Сборка asm = система.Отражение.Собрание.GetExecutingAssembly();

Форма activate = null;
foreach (форма frm в системе.Приложение.OpenForms)
{
если (frm.Name == имя формы)
{
активировать = frm;
перерыв;
}
}
if (activate == null)
{
активировать = (форма)asm.Метод createinstance(sFormName);
активировать.Владелец = это;
активировать.Покажите();
}
еще
активировать.Сосредоточить();
}


Рейтинг:
2

Sergey Alexandrovich Kryukov

Во-первых, это не очень хороший вопрос: 1) нет такой вещи, как "открыть форму", даже если вы можете "закрыть" форму; 2) ты покажите форму, чтобы было очевидно, что вам решать, что открывать, а что нет; вы не можете задавать вопросы каждый раз, когда вам нужно решить что-то столь тривиальное; если бы вы спросили, как это сделать красиво, это была бы другая история.

Итак, при разработке второго пункта выше вы можете использовать ленивая инициализация шаблон или, нагрузка по вызову, что, вероятно, лучше всего в таких случаях: http://en.wikipedia.org/wiki/Lazy_initialization#C.23[^].

В очень простой форме вы должны просто инкапсулировать метод отображения формы:

class SomeForm : Form { // for example, your main form;
                        // this class does not have to be a form...

    void ShowOneMoreForm() {
        if (oneMoreForm == null) {
            oneMoreForm = new OneMoreForm.Create();
            //...
            oneMoreForm.Owner = this; // very important item
            //..
        } //if
        oneMoreForm.Show();
    } //ShowOneMoreForm

    OneMoreForm oneMoreForm; // initialized as null

} //class SomeForm
Просто, не правда ли?

Это гарантирует, что у вас есть только одна форма этого типа, и что она сохраняет свое состояние (потому что вы никогда не создавали ее во второй раз). Иногда такой подход решает гораздо более сложную задачу: некоторые операции при реализации ShowOneMoreForm не может быть выполнено на ранней стадии, например, в его конструкторе, или когда основная форма не настроена должным образом. Иногда бывает трудно найти подходящий момент для этого. И в этом решении load-on-call вы создаете и настраиваете эту форму только тогда, когда она действительно требуется в самый первый раз, скажем, когда пользователю нужно работать с ней.

—СА


[no name]

Привет Сергей;
Вы предлагаете хороший, общий совет - но ваше решение игнорирует требование OP, чтобы форма была создана путем отражения. Определение toolstrip было включено, чтобы показать, что имя класса формы не может быть определено до времени выполнения. Я бы пошел дальше и предположил, что полоса инструментов содержит несколько подменю, подобных этому. Было бы неплохо объявить переменную определенного типа для каждой формы, но я не вижу, как это было бы возможно, если требуется самоанализ (например, определяемый динамическим плагином, таблицей или конфигурационным файлом).

Sergey Alexandrovich Kryukov

"Созданный отражением" должен быть частью требований. Развитие должно быть последовательным. Если какой-то документ представляет собой набор требований, определяющих, что должно быть реализовано (поведение), то он не должен указывать "как". Нарушение такого простого принципа было бы верным способом блокировать развитие.

Во всяком случае, я не вижу, как мое решение мешает использовать отражение... И я не вижу ничего, что говорило бы о том, что имя класса (имя??? самого класса? Но тогда она решается с помощью ООП) не определяется до начала выполнения. "Типо-специфическая переменная" для каждой формы может быть грязным стилем программирования. Опять же, нечто подобное можно сделать с помощью ООП или ООП с интерфейсами...

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

—СА

[no name]

Ваша идея ясна, но оставляет открытыми многочисленные возможности. Мне любопытно, как бы вы использовали это решение из метода кликмену?

Sergey Alexandrovich Kryukov

It depends on the set of form types. In most extreme general case, when all the concrete forms are totally unknown at compile time, they have to be give something known at compile type. The best approach is this: you make them all implementing some interface (plug-in interface, I call it). Then the host application gets some assembly, in extreme general case, not known during compile time, so it will be loaded during runtime. Then, with reflection, you find all types implementing this interface and perform instantiation of those forms. I do even better; I also define assembly-level attribute used to claim what types should be considered as plug-in implementation, it cuts the search down (for example, to no search at all). And then we use the interface. The plug-in forms have some identifier (name, description) which goes to the menu of the host application. When menu is activated, the appropriate form is found among plug-ins. (It's good to use the dictionary to hold all the references to them.)

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

—СА

[no name]

Потрясающий. Спасибо, Сергей!

Sergey Alexandrovich Kryukov

Добро пожаловать.
—СА