Як повернути значення з Форми в C #?


185

У мене є основна форма (назвемо це frmHireQuote), яка є дочірньою основною формою MDI (frmMainMDI), яка показує іншу форму (frmImportContact) через ShowDialog () при натисканні кнопки.

Коли користувач натискає "OK" на frmImportContact, я хочу передати кілька рядкових змінних назад до деяких текстових полів на frmHireQuote.

Зауважте, що може бути декілька примірників frmHireQuote, очевидно, важливо повернутися до екземпляра, який викликав цей екземпляр frmImportContact.

Який найкращий метод зробити це?

Відповіді:


367

Створіть деякі загальнодоступні Властивості на своїй під-формі так

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;
    }
}

Additionaly , якщо ви хочете , щоб скасувати з суб-форми , ви можете просто додати кнопку в форму і встановіть його DialogResult до , Cancelі ви можете також встановити CancelButton властивість форми на зазначеній кнопці - це дозволить клавішу виходу , щоб скасувати з форми.


33
Пару важливих вад. Форма, яка відображається за допомогою ShowDialog (), не розміщена. Ви повинні використовувати , використовуючи заяву тут. ShowDialog () повертає значення DialogResult, не ігноруйте його або ви спробуєте використовувати властивості діалогу, коли користувач скасував діалогове вікно.
Ганс Пасант

Ура, я це врахував.
Jez Clark

Міні-критика: до набору додається крапка з комою.
Б. Клей Шеннон

16

Я зазвичай створюю статичний метод у формі / діалозі, який я можу викликати. Це повертає успіх (кнопку ОК) або невдачу, а також значення, які потрібно заповнити.

 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
   }
}

Використовували і цей підхід, працює добре. Однак префіксація класу результатів frmможе (і що я робив, коли я читав) призводить до плутанини ...
Річард Друг

Я просто повторно використав ім’я з питання (+ швидке введення тексту). Я зміню його на краще ім’я.
GvS

6

Знайшов ще одну невелику проблему з цим кодом ... або, принаймні, це було проблематично, коли я намагався його реалізувати.

Кнопки в 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

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


0

Я дуже багато використовую 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
}

Тепер, вручну або за допомогою GUI, попросіть MDIparent реагувати на події дочірніх форм.

Але за допомогою Owr 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);

Простий механізм перемикання зазвичай достатній для передачі подій у відповідні форми.


0

Якщо ви хочете передати дані в 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

Спочатку потрібно визначити атрибут у 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";
 }

Виклик форми2 (дитина) від форми1 (батьків):

  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

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


Гей, там! Чи можете ви детальніше розглянути свою відповідь і, можливо, надати зразок коду, щоб допомогти майбутнім користувачам?
Джеремі Гарріс

0

делегати - найкращий варіант для надсилання даних з однієї форми в іншу.

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");
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.