Как вернуть значение из формы в C #? - PullRequest
167 голосов
/ 08 марта 2011

У меня есть основная форма (назовем ее frmHireQuote), которая является дочерней по отношению к основной форме MDI (frmMainMDI), которая показывает другую форму (frmImportContact) через ShowDialog () при нажатии кнопки.

Когда пользователь нажимает «OK» на frmImportContact, я хочу передать несколько строковых переменных обратно в некоторые текстовые поля в frmHireQuote.

Обратите внимание, что может быть несколько экземпляров frmHireQuote, очевидно, что я должен вернуться назадк экземпляру, который вызвал этот экземпляр frmImportContact.

Какой лучший способ сделать это?

Ответы [ 9 ]

326 голосов
/ 08 марта 2011

Создайте несколько общедоступных свойств в вашей подформе , например,

public string ReturnValue1 {get;set;} 
public string ReturnValue2 {get;set;}

затем установите это в вашей субформе обработчик нажатия кнопки ОК

private void btnOk_Click(object sender,EventArgs e)
{
    this.ReturnValue1 = "Something";
    this.ReturnValue2 = DateTime.Now.ToString(); //example
    this.DialogResult = DialogResult.OK;
    this.Close();
}

Затем в вашей форме frmHireQuote , когда вы открываете подформу

using (var form = new frmImportContact())
{
    var result = form.ShowDialog();
    if (result == DialogResult.OK)
    {
        string val = form.ReturnValue1;            //values preserved after close
        string dateString = form.ReturnValue2;
        //Do something here with these values

        //for example
        this.txtSomething.Text = val;
    }
}

Дополнительно, если вы хотите отменить из субформы , вы можете просто добавить кнопку в форму и установить для ее DialogResult значение Cancel, а также установить CancelButton свойство формы для указанной кнопки - это позволит клавише Escape отменить выход из формы.

13 голосов
/ 08 марта 2011

Обычно я создаю статический метод в форме / диалоге, который я могу вызвать.Это возвращает успех (кнопка ОК) или неудачу вместе со значениями, которые необходимо заполнить.

 public class ResultFromFrmMain {
     public DialogResult Result { get; set; }
     public string Field1 { get; set; }


 }

И в форме:

public static ResultFromFrmMain Execute() {
     using (var f = new frmMain()) {
          var result = new ResultFromFrmMain();
          result.Result = f.ShowDialog();
          if (result.Result == DialogResult.OK) {
             // fill other values
          }
          return result;
     }
}

Для вызова вашей формы;

public void MyEventToCallForm() {
   var result = frmMain.Execute();
   if (result.Result == DialogResult.OK) {
       myTextBox.Text = result.Field1; // or something like that
   }
}
6 голосов
/ 16 ноября 2012

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

Кнопки в frmMain не возвращают совместимое значение, используя VS2010, я добавил следующее ивсе стало работать нормально.

public static ResultFromFrmMain Execute() {
     using (var f = new frmMain()) {

          f.buttonOK.DialogResult = DialogResult.OK;
          f.buttonCancel.DialogResult = DialogResult.Cancel;

          var result = new ResultFromFrmMain();
          result.Result = f.ShowDialog();

          if (result.Result == DialogResult.OK) {
             // fill other values
          }
          return result;
     }
}

После добавления значений двух кнопок диалог работал отлично!Спасибо за пример, это действительно помогло.

1 голос
/ 08 октября 2013

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

0 голосов
/ 18 апреля 2019

делегаты - лучший вариант для отправки данных из одной формы в другую.

public partial class frmImportContact : Form
{
     public delegate void callback_data(string someData);
    public event callback_data getData_CallBack;

    private void button_Click(object sender, EventArgs e)
    {
      string myData = "Top Secret Data To Share";
      getData_CallBack(myData);
    }

}

public partial class frmHireQuote : Form
{
     private void Button_Click(object sender, EventArgs e)
    {

      frmImportContact obj = new frmImportContact();
      obj.getData_CallBack += getData;
    }

    private void getData(string someData)
    {
         MessageBox.Show("someData");
    }
}
0 голосов
/ 23 декабря 2018

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

0 голосов
/ 11 февраля 2018

Сначала вы должны определить атрибут в form2 (дочерний), вы обновите этот атрибут в form2, а также из form1 (родительский):

 public string Response { get; set; }

 private void OkButton_Click(object sender, EventArgs e)
 {
    Response = "ok";
 }

 private void CancelButton_Click(object sender, EventArgs e)
 {
    Response = "Cancel";
 }

Вызов form2 (дочерний) из form1 (родительский):

  using (Form2 formObject= new Form2() )
  {
     formObject.ShowDialog();

      string result = formObject.Response; 
      //to update response of form2 after saving in result
      formObject.Response="";

      // do what ever with result...
      MessageBox.Show("Response from form2: "+result); 
  }
0 голосов
/ 23 мая 2017

Если вы хотите передать данные в form2 из form1 без передачи как новый form(sting "data");

Сделайте это в форме 1

using (Form2 form2= new Form2())
{
   form2.ReturnValue1 = "lalala";
   form2.ShowDialog();
}

в форме 2 добавьте

public string ReturnValue1 { get; set; }

private void form2_Load(object sender, EventArgs e)
{
   MessageBox.Show(ReturnValue1);
}

Также вы можете использовать значение в form1, например, если вы хотите поменять что-то в form1

только в форме1

textbox.Text =form2.ReturnValue1
0 голосов
/ 08 марта 2015

Я довольно часто использую MDI, мне он нравится гораздо больше (где его можно использовать), чем несколько плавающих форм.

Но чтобы извлечь из этого максимум, нужно разобраться со своими собственными событиями.,Это делает жизнь намного проще для вас.

Пример скелета.

Есть ваши собственные типы прерываний,

//Clock, Stock and Accoubts represent the actual forms in
//the MDI application. When I have multiple copies of a form
//I also give them an ID, at the time they are created, then
//include that ID in the Args class.
public enum InteruptSource
{
    IS_CLOCK = 0, IS_STOCKS, IS_ACCOUNTS
}
//This particular event type is time based,
//but you can add others to it, such as document
//based.
public enum EVInterupts
{
    CI_NEWDAY = 0, CI_NEWMONTH, CI_NEWYEAR, CI_PAYDAY, CI_STOCKPAYOUT, 
   CI_STOCKIN, DO_NEWEMAIL, DO_SAVETOARCHIVE
}

Тогда ваш собственный тип Args

public class ControlArgs
{
    //MDI form source
    public InteruptSource source { get; set; }
    //Interrupt type
    public EVInterupts clockInt { get; set; }
    //in this case only a date is needed
    //but normally I include optional data (as if a C UNION type)
    //the form that responds to the event decides if
    //the data is for it.
    public DateTime date { get; set; }
    //CI_STOCKIN
    public StockClass inStock { get; set; }

}

Затем используйте делегата в вашем пространстве имен, но вне класса

namespace MyApplication
{
public delegate void StoreHandler(object sender, ControlArgs e);
  public partial class Form1 : Form
{
  //your main form
}

Теперь, либо вручную, либо с помощью графического интерфейса, MDIparent должен реагировать на события дочерних форм.

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

Просто укажите, чтобы все ваши коды событий mdiparent указывали на одну функцию,

        calendar.Friday += new StoreHandler(MyEvents);
        calendar.Saturday += new StoreHandler(MyEvents);
        calendar.Sunday += new StoreHandler(MyEvents);
        calendar.PayDay += new StoreHandler(MyEvents);
        calendar.NewYear += new StoreHandler(MyEvents);

Обычно достаточно простого механизма переключения для передачи событий в соответствующие формы.

...