C # Formdaki bir değer nasıl döndürülür?


185

ShowDialog () üzerinden başka bir formu (frmImportContact) ShowDialog () üzerinden gösteren bir ana MDI formunun (frmMainMDI) alt bir çocuğu olan ana form (frmHireQuote diyelim) var.

Kullanıcı frmImportContact 'Tamam' tıkladığında, ben birkaç dize değişkenleri frmHireQuote bazı metin kutularına geri geçirmek istiyorum.

FrmHireQuote'un birden çok örneği olabileceğini unutmayın, bu frmImportContact örneğini geri döndüren örneğe geri dönmem önemlidir.

Bunu yapmanın en iyi yöntemi nedir?

Yanıtlar:


367

Senin bazı kamu Özellikler 'oluşturma alt formun şöyle

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

ardından bunu alt form ok düğmesi tıklama işleyicinizin içine ayarlayın

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

Sonra frmHireQuote formunuzda , alt formu açtığınızda

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

Eğer dışarı iptal etmek istiyorsanız Additionaly eğer alt formun sadece forma bir düğme eklemek ve ayarlayabilirsiniz DialogResult için Cancelve ayrıca ayarlayabilirsiniz CancelButton söyledi düğmeye formun özelliği - bu iptal etmek kaçış anahtarını sağlayacak şeklinde.


33
Birkaç önemli kusur. ShowDialog () ile görüntülenen bir form atılmaz. Burada using ifadesini kullanmalısınız . ShowDialog () bir DialogResult değeri döndürür, yoksaymayın ya da kullanıcı iletişim kutusunu iptal ettiğinde iletişim kutusu özelliklerini kullanmaya çalışırsınız.
Hans Passant

Şerefe, ben bunu açıkladım.
Jez Clark

Mini eleştiri: set eklenmiş noktalı virgül gerektirir.
B. Clay Shannon

16

Normalde form / iletişim kutusunda arayabileceğim statik bir yöntem oluştururum. Bu, doldurulması gereken değerlerle birlikte başarıyı (Tamam düğmesi) veya başarısızlığı döndürür.

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


 }

Ve formda:

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

Formunuzu aramak için;

public void MyEventToCallForm() {
   var result = frmMain.Execute();
   if (result.Result == DialogResult.OK) {
       myTextBox.Text = result.Field1; // or something like that
   }
}

Bu yaklaşımı da kullandık, iyi çalışıyor. Ancak sonuç sınıfının önekini canla frm(ve sadece okuduğumda) karıştırmak karışıklığa yol açıyor ...
Richard Friend

Sadece sorudan ismi tekrar kullandım (+ hızlı yazarak). Daha iyi bir isimle değiştireceğim.
GvS

6

Bu kodda başka bir küçük sorun daha buldum ... ya da en azından ben uygulamaya çalıştığımda sorun oldu.

FrmMain düğmeleri uyumlu bir değer döndürmüyor, VS2010 kullanarak aşağıdakileri ekledim ve her şey iyi çalışmaya başladı.

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

İki düğme değerini ekledikten sonra iletişim kutusu harika çalıştı! Örnek için teşekkürler, gerçekten yardımcı oldu.


1

Ben sadece bir şey referans olarak yapıcı koymak, böylece alt form değerini değiştirebilir ve ana form alt formdan yeni veya değiştirilmiş nesne alabilirsiniz.


1

Eğer veri geçmek istiyorsanız form2den form1yeni gibi geçmedenform(sting "data");

Form 1'de bunu yapın

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

in form 2 ekleyin

public string ReturnValue1 { get; set; }

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

Ayrıca, bir form1şeyi takas etmek istiyorsanız, bu şekilde bir değer kullanabilirsiniz .form1

sadece form1'de

textbox.Text =form2.ReturnValue1

0

MDI'yi çok fazla kullanıyorum, birden fazla yüzen formdan çok daha fazla (kullanılabileceği yerde) seviyorum.

Ancak ondan en iyi şekilde yararlanmak için kendi olaylarınızla başa çıkmanız gerekir. Hayatı sizin için çok daha kolay hale getirir.

İskelet örneği.

Kendi interupt tipleriniz var,

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

Sonra kendi Args türünüz

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

}

Ardından, temsilci ad alanınızda, ancak sınıf dışında kullanın

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

Şimdi el ile veya GUI kullanarak, MDIparent alt formların olaylara yanıt var.

Ancak owr Args ile bunu tek bir işleve indirgeyebilirsiniz. ve kesintileri kesmek için iyi, ancak başka şekillerde de yararlı olabilir.

Tüm mdiparent olay kodlarınızın tek bir işlevi göstermesini sağlayın,

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

Basit bir anahtar mekanizması genellikle olayları uygun formlara aktarmak için yeterlidir.


0

İlk önce form2'de (child) özniteliği tanımlamanız gerekir, bu özniteliği form2'de ve ayrıca form1'den (üst) güncelleştirirsiniz:

 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'den (üst öğe) form2 (alt öğe) çağrısı:

  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

Değeri ayarlayan formdaki bir olayı yükseltirim ve değer değişikliği ile ilgilenmesi gereken form (lar) da o etkinliğe abone olurum.


Selam! Cevabınız hakkında biraz daha ayrıntı verebilir ve gelecekteki kullanıcılara yardımcı olacak bir kod örneği sağlayabilir misiniz?
Jeremy Harris

0

temsilciler bir formdan diğerine veri göndermek için en iyi seçenektir.

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");
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.