Как получить метод в главной форме, чтобы он выполнялся в основной форме всякий раз, когда я выполняю какие-либо действия во вторичной форме?

Я пытаюсь обновить свои данные в основной форме всякий раз, когда я изменяю какой-либо параметр во вторичной форме.

Возможное решение:

Сделайте метод общедоступным на 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, но это, вероятно, несовместимо с остальной частью вашего кода.

Другие вопросы по тегам