Проблема события делегата FormClosing

У меня есть две формы с именами «mainForm» и «addRslt». Идея заключается в том, что когда пользователи нажимают кнопку в mainForm, форма addRslt вызывает Show(), а затем пользователь заполняет TreeView. Теперь, когда пользователь ХОЧЕТ ЗАКРЫТЬ эту форму addRslt, программа вместо этого Скроет() форму (используя e.Cancel = true;), так что позже если пользователь снова откроет это, он / она может добавить больше вещей в TreeView.

В моей mainForm у меня есть кнопка для отображения этой формы addRslt, а также внутри кода нажатия этой кнопки есть мой делегат FormClosing, который обнаружит и скопирует содержимое TreeView в форме addRslt в TreeView в mainForm.

Теперь проблема в том, что я хочу проверить дублированные узлы и не добавлять их в TreeView в mainForm. Это сделано правильно, но у меня также есть окно сообщения, которое сообщает пользователю, что программа не добавила существующие узлы! до сих пор все в порядке.. НО проблема в том, что каждый раз, когда я это делаю, это окно сообщений появляется N+1 раз! Я имею в виду, если я делаю это в первый раз, это окно сообщения появляется 2 раза и т. д.

Вот мой код! Извините за долгий рассказ!

    private void menuFileAddTestResults_Click(object sender, EventArgs e)
    {
        addRslt.Show();

        addRslt.FormClosing += delegate
        {
            foreach (TreeNode node in addRslt.treeViewSelectedFiles.Nodes)
            {
                TreeNode newNode = new TreeNode();
                newNode.Text = node.Text;
                newNode.Name = node.Name;
                newNode.Tag = node.Tag;

                if (!treeViewTestFiles.Nodes.ContainsKey(node.Name))
                {
                    treeViewTestFiles.Nodes.Add(newNode);
                }
                else
                {
                    countExist++;
                }
            }

            if (countExist > 0)
            {
                MessageBox.Show(countExist.ToString() + " Test files are already exist in the list!");
            }

            countExist = 0;
        };
    }

person Saeid Yazdani    schedule 11.04.2011    source источник


Ответы (2)


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

person Jon Skeet    schedule 11.04.2011
comment
Спасибо, Джон. Вы имеете в виду, что проблема в том, что я использовал «+=»? Я пробовал только с '=', но не может быть скомпилирован. как это сделать? И не могли бы вы рассказать более подробно о лучшем способе сделать это? - person Saeid Yazdani; 11.04.2011
comment
@Sean87: Да, += добавляет дополнительный обработчик событий. Вы не можете использовать =, так как это модель издатель/подписчик - вы не можете заменять подписки, только добавлять/удалять их. Просто переместите эту подписку на обработчик событий туда, где вы инициализируете addRslt (или сразу после InitializeComponent, если он там есть), чтобы добавить только один обработчик, как бы часто ни отображалась форма. С другой стороны, переместите код в отдельный метод и подпишитесь на него так же, как вы подписались на обработчик Click в первую очередь. - person Jon Skeet; 11.04.2011

Похоже, вы постоянно добавляете свою встроенную реализацию в многоадресный делегат.

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

person Jodrell    schedule 11.04.2011