Bagaimana cara mengembalikan nilai dari Formulir di C #?

185

Saya memiliki formulir utama (sebut saja frmHireQuote) yang merupakan anak dari formulir MDI utama (frmMainMDI), yang memperlihatkan formulir lain (frmImportContact) melalui ShowDialog () saat sebuah tombol diklik.

Ketika pengguna mengklik 'OK' di frmImportContact, saya ingin meneruskan beberapa variabel string kembali ke beberapa kotak teks di frmHireQuote.

Perhatikan bahwa mungkin ada beberapa contoh frmHireQuote, jelas penting bahwa saya kembali ke contoh yang disebut turunan frmImportContact ini.

Apa metode terbaik untuk melakukan ini?

Jez Clark
sumber

Jawaban:

367

Buat beberapa Properti publik di sub-formulir Anda seperti itu

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

kemudian atur ini di dalam sub-form klik tombol pawang Anda

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

Kemudian pada Anda bentuk frmHireQuote , ketika Anda membuka sub-form

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

Tambahan pula jika Anda ingin membatalkan sub-formulir, Anda bisa menambahkan tombol ke formulir dan mengatur DialogResult menjadi Canceldan Anda juga dapat mengatur properti CancelButton dari formulir ke tombol said - ini akan memungkinkan tombol escape untuk membatalkan dari bentuk.

Richard Friend
sumber
33
Beberapa kekurangan penting. Formulir yang ditampilkan dengan ShowDialog () tidak dibuang. Anda harus menggunakan pernyataan penggunaan di sini. ShowDialog () mengembalikan nilai DialogResult, jangan abaikan atau Anda akan mencoba menggunakan properti dialog ketika pengguna membatalkan dialog.
Hans Passant
Ceria, saya sudah memperhitungkan ini.
Jez Clark
Mini-kritik: set kebutuhan titik koma ditambahkan.
B. Clay Shannon
16

Saya biasanya membuat metode statis pada form / dialog, yang bisa saya panggil. Ini mengembalikan keberhasilan (tombol OK) atau kegagalan, bersama dengan nilai-nilai yang perlu diisi.

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


 }

Dan pada formulir:

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

Untuk memanggil formulir Anda;

public void MyEventToCallForm() {
   var result = frmMain.Execute();
   if (result.Result == DialogResult.OK) {
       myTextBox.Text = result.Field1; // or something like that
   }
}
GvS
sumber
Telah menggunakan pendekatan ini juga, bekerja dengan baik. Namun mengawali kelas hasil dengan frmcan (dan baru saja dilakukan ketika saya membacanya) menyebabkan kebingungan ...
Richard Friend
Saya baru saja menggunakan kembali nama dari pertanyaan (+ ketikan cepat). Saya akan mengubahnya menjadi nama yang lebih baik.
GvS
6

Menemukan masalah kecil lainnya dengan kode ini ... atau setidaknya bermasalah ketika saya mencoba mengimplementasikannya.

Tombol-tombol di frmMain tidak mengembalikan nilai yang kompatibel, menggunakan VS2010 saya menambahkan yang berikut dan semuanya mulai berfungsi dengan baik.

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

Setelah menambahkan dua nilai tombol, dialognya berhasil! Terima kasih untuk contohnya, ini sangat membantu.

DaveHelton
sumber
1

Saya hanya memasukkan konstruktor sesuatu dengan referensi, sehingga subformulir dapat mengubah nilainya dan bentuk utama bisa mendapatkan objek baru atau yang dimodifikasi dari subformulir.

SerG
sumber
0

Saya menggunakan MDI cukup banyak, saya sangat menyukainya (di mana dapat digunakan) daripada beberapa bentuk mengambang.

Tetapi untuk mendapatkan yang terbaik dari itu, Anda harus memahami acara Anda sendiri. Itu membuat hidup jadi lebih mudah bagi Anda.

Contoh kerangka.

Memiliki tipe interupt Anda sendiri,

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

Kemudian tipe Args Anda sendiri

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

}

Kemudian gunakan delegasi di dalam namespace Anda, tetapi di luar kelas

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

Sekarang baik secara manual atau menggunakan GUI, minta MDIparent menanggapi peristiwa bentuk anak.

Tetapi dengan owr Args Anda, Anda dapat mengurangi ini menjadi satu fungsi. dan Anda dapat memiliki ketentuan untuk menghentikan interupsi, baik untuk debugging, tetapi dapat bermanfaat dengan cara lain juga.

Hanya minta al dari kode acara mdiparent Anda menunjuk ke satu fungsi,

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

Mekanisme sakelar sederhana biasanya cukup untuk meneruskan acara ke formulir yang sesuai.

Bob
sumber
0

Jika Anda ingin meneruskan data form2dari form1tanpa melewati seperti baruform(sting "data");

Lakukan seperti itu di formulir 1

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

dalam formulir 2 tambahkan

public string ReturnValue1 { get; set; }

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

Anda juga dapat menggunakan nilai form1seperti ini jika Anda ingin menukar sesuatuform1

hanya di form1

textbox.Text =form2.ReturnValue1
Matas Lesinskas
sumber
0

Pertama, Anda harus mendefinisikan atribut di form2 (child), Anda akan memperbarui atribut ini di form2 dan juga dari form1 (induk):

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

Memanggil form2 (anak) dari form1 (induk):

  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); 
  }
Wajid khan
sumber
0

Saya mengangkat suatu peristiwa dalam bentuk pengaturan nilai dan berlangganan ke acara itu dalam bentuk yang perlu berurusan dengan perubahan nilai.

Edward Miller
sumber
Hai yang disana! Bisakah Anda menguraikan sedikit lebih banyak tentang jawaban Anda dan mungkin memberikan contoh kode untuk membantu pengguna di masa depan?
Jeremy Harris
0

delegasi adalah pilihan terbaik untuk mengirim data dari satu formulir ke formulir lainnya.

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");
    }
}
Sayed Muhammad Idrees
sumber