Как получить метод в главной форме, чтобы он выполнялся в основной форме всякий раз, когда я выполняю какие-либо действия во вторичной форме?
Я пытаюсь обновить свои данные в основной форме всякий раз, когда я изменяю какой-либо параметр во вторичной форме.
Возможное решение:
Сделайте метод общедоступным на Form1
(основная форма) вот так:
public void updatedata()
{
//data update
}
И затем назовите это на вторичной форме:
Form1.updatedata()
Это не работает, и я верю, что это потому, что он пытается обновить Form2
Я использую частичные классы, но я не очень хорошо разбираюсь в них.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
И вторичный:
public partial class formOpConfig : Form
{
private Form1 Opener { get; set; }
public formOpConfig(Form1 opener)
{ //initialize component
}
}
3 ответа
Я чувствую, что наверняка есть дублирующий вопрос, чтобы соответствовать этому. Но я не смог его найти.
Учитывая код, который вы разместили, ваша попытка, вероятно, сработала бы, если бы вы использовали Opener.updatedata()
вместо Form1.updatedata()
, Но это все равно не было бы лучшим решением.
Комментатор Джон Сондерс прав, правильный способ сделать это - объявить event
в formOpConfig
, а затем иметь Form1
подпишись на него. Это выглядит примерно так:
public partial class formOpConfig : Form
{
public event EventHandler UpdateData;
private void SomethingHappens()
{
// do stuff...
OnUpdateData();
// maybe do other stuff too...
}
private void OnUpdateData()
{
EventHandler handler = UpdateData;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
Вышеуказанное объявляет event
и вызывает это событие (вызывает обработчики) в соответствующее время (т.е. когда SomethingHappens()
).
public partial class Form1 : Form
{
private void OpenConfigForm()
{
OpenConfigForm opConfig = new formOpConfig();
opConfig.UpdateData += (sender, e) => updatedata();
}
// Note that this method is private...no one else should need to call it
private void updatedata()
{
//data update
}
}
Вот, Form1
подписывается на событие, когда он создает экземпляр formOpConfig
(Я предполагаю Form1
это то, что создает этот экземпляр), и когда вызывается его обработчик, он вызывает updatedata()
метод, который вы уже написали.
Таким образом, два класса остаются разъединенными; т.е. они на самом деле не зависят друг от друга, больше, чем они должны быть (в частности, formOpConfig
класс не должен ничего знать о Form1
).
Хороший способ сделать это - использовать событие.
Это позволяет вам отделить формы, потому что они даже не нуждаются в ссылке друг на друга; По сути, событие - это способ для вашей второй формы сообщить всем, кто может слушать (без необходимости точно знать, кто), что произошло что-то интересное, и дать им некоторую информацию об этом интересном событии, которое они могут использовать.
Связанная статья даст вам гораздо больше деталей, чем приведенная ниже, и это лишь краткое представление о том, как это сделать; Я бы порекомендовал проработать урок!
Механизм, посредством которого это происходит, состоит в том, что любой, кто хочет знать об интересных событиях на Form2
должен подписаться на соответствующее событие на Form2
; тогда всякий раз, когда Form2
хочет сообщить своим слушателям, что что-то произошло, он вызывает любые обработчики событий, которые были присоединены к событию.
Поскольку у события может быть несколько обработчиков, это действительно отличный способ отсоединить компоненты вашего приложения.
Быстрое демо
(примечание: приведенный ниже код находится вне головы, поэтому не тестировался, не обрабатывал ошибки и т. д.)
Прежде всего, вам нужно объявить класс, который можно использовать для отправки интересных данных прослушивающим сторонам. Этот класс должен наследовать от System.EventArgs
public class InterestingEventArgs:EventArgs
{
public string AnInterestingFact {get;private set;}
public InterestingEventArgs(string fact)
{
AnInterestingFact =fact;
}
}
Неважно, где вы объявляете это, пока это видно обоим Form1
а также Form2
,
Далее вы должны объявить событие на Form2
, он должен быть публичным и должен выглядеть так:
public event EventHandler<InterestingEventArgs> SomethingInterestingHappened;
Теперь вам нужно решить, когда вы собираетесь рассказать заинтересованным сторонам об этом событии. Предположим, у вас есть кнопка Form2
и вы хотите поднять событие, когда вы нажимаете на него. Таким образом, в обработчике Click для кнопки вы можете иметь такой код:
public void btnRaiseEvent_Clicked(object sender, EventArgs e)
{
var fact= txtFact.Text;
var handler = SomethingInterestingHappened;
if (handler!=null)
{
handler(this,new InterestingEventArgs(fact));
}
}
и, наконец, вот как код может выглядеть из Form1 при запуске Form2, скажем, вы нажимаете кнопку на Form1
запускать Form2
:
public void btnShowForm2_Clicked(object sender, EventArgs e)
{
var child = new Form2();
child.SomethingInterestingHappened+=OnSomethingInterestingHappened;
child.Show();
}
Наконец, вам нужно написать обработчик событий Form1
это будет вызвано, когда событие поднято:
void OnSomethingInterestingHappened(object sender, InterestingEventArgs e)
{
MessageBox.Show("Did you know? " + e.AnInterestingFact);
}
Похоже, вы передали ссылку на объект Form1 в конструкторе. Используй это:
public partial class formOpConfig : Form
{
private Form1 Opener { get; set; }
public formOpConfig(Form1 opener)
{
Opener = opener;
}
private void updateForm1()
{
Opener.updatedata();
}
}
Form1 - это класс, а не объект. Вы можете сказать Form1.updatedata(), если вы делаете updatedata () статическим методом класса Form1, но это, вероятно, несовместимо с остальной частью вашего кода.