2009-10-01 4 views
0

Ситуация: C#, .NET 3.5, WinFormsC# Winforms: передать функцию из одной формы в другую?

Цель: Form1 имеет кнопки, которая может быть включена с помощью конструктора. И.Е. кнопка будет отображаться только в том случае, если я вызываю новый Form1 (true). Мы хотели бы иметь возможность передать метод через некоторый параметр из Form2 в Form1 (не обязательно должен быть в конструкторе Form1), а при нажатии Form1.Button1 должно выполняться Form2.<SomeMethod>.

Мы знаем, что мы могли бы создать делегат/событие в Form1 и из Form2 сделать что-то вроде:

Form1.SomeDelegate += new ..... (MyMethodInForm2); 

..., а затем в Form1_ButtonClick обстреливают событие, которое, в свою очередь, будет делать магию в Form2.

Но мы задавались вопросом, была ли более элегантная/новая/современная версия (Анонимные методы? Лямбда-выражения и т. Д.), Чтобы выполнить это.

Идея заключается в том, что форма «любая» может инициировать класс Form1 и передавать свой собственный метод, который будет выполняться при нажатии кнопки Form1; но вместо обратного вызова вызывающему (form2,3, .. n) Form1 выполняет переданную функцию (которая, возможно, находится внутри вызывающего абонента). Нам действительно не нужны эти функции, чтобы иметь параметры на данный момент.

Примечание: Образцы кода содержат простые имена переменных/объектов и не берутся из реальной жизни, пожалуйста, игнорируйте простоту.

UPDATE Извините за не более конкретным, я думаю, что я буду продолжать использовать модель делегата/событие, но для справки, вот что я думаю, что это лучше описание situtation:

Form1 является общую форму, которая принимает список элементов и отображает их. Мы можем передавать типы сотрудников или типы лиц или любые «Т». Он работает нормально. Мы получили требование от клиента, спрашивая, можно ли добавить дополнительную кнопку к этому маленькому Form1, который, если щелкнуть, откроет другую форму/выполнит какой-либо метод.

Таким образом, если я использую Form1, я мог бы - время выполнения - сказать кнопке, чтобы открыть EmployeeForm, тогда как если я использую Form1, ту же самую кнопку может открыть форму PersonForm. Теперь открытие формы - это не единственное, что у нас было бы для этой кнопки, но это проблема звонящего.

Прямо сейчас, я сделал то, что мы сказали: делегат/событие на этой Форме1 и в форме «вызова» мы делаем Form1.theEvent + = материал, чтобы подписаться на это событие. Я просто хотел узнать, есть ли лучший способ сделать это, так как это мы делаем в .NET 2.0, и мы только начали использовать .NET 3.5.

+0

Я думаю, что я хотел, чтобы сделать его более «API» дружественным, чем просто чтобы пользователь API знал, что он должен подписаться на событие XX ... –

ответ

1

Похоже, вы дважды описываете одно и то же.

Подписывание события делает именно это - передает функцию Form1, которая затем выполняет функцию при поднятии события.

Вы можете подписаться на мероприятие, используя выражение лямбда, если хотите, но вам этого не нужно.

Конечно, вы могли бы поместить делегат в качестве параметра конструктора Form1, если хотите, но я не вижу в этом случае большого преимущества.

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

+0

Я предполагаю, что его эстетика зависит от того, использует ли Form1 ALWAYS такого рода делегат. Если это так, передача чего-то в конструкторе делает немного более эстетичным, поскольку он связывает это требование с API. Однако это необязательно, и эта форма может использоваться другими способами, тогда как Джон утверждает, что нет оснований делать это по-другому. – Quibblesome

1

Не совсем уверен, что вы имеете в виду с формой, но вы можете отправить Func. Например:

public class MyForm<T> 
{ 

    private readonly Func<T, bool> predicate; 

    public MyForm(Func<T, bool> predicate) { this.predicate = predicate } 

    private void SomeMethod() 
    { 
     bool result = predicate(); 
     // Do something 
    } 
} 

var form = new MyForm(x => x.Number < 5); 
+0

Вы также можете использовать действие , которое всегда будет возвращать пустоту или предикат , который всегда будет возвращать bool – Jabezz

0

1st: вы должны объявить публичное событие в Form1.
2nd: вам следует вызывать событие, когда оно отправляется в Form1, например Button1_Click

+0

Jon, если ему нужно начать делать это в какое-то особое время или не используется, всегда передавая его в качестве параметра или в выражении лямбда может уменьшить скорость. – Behrooz

0

Из того, что я могу сказать, Form2 является немодальным диалогом, который Form1 может обновить. Однако Form2 еще не был создан.

Очевидным способом выполнения обновления Form2 является использование модели событий, как у вас, с использованием композиции и передачи Form1 в ее конструктор.

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

Если вы хотите Form2 обновить любого типа, то простой интерфейс позволит решить проблема.

0

Другой подход заключается в разоблачать Click событие кнопки, определяя «прокси-событие» на общей форме:

public class MyForm<T> : Form 
{ 

    public event EventHandler MyClick 
    { 
     add { this.theButton.Click += value; } 
     remove { this.theButton.Click -= value; } 
    } 

    // ... 
} 
Смежные вопросы