web-dev-qa-db-fra.com

Comment retourner une valeur d'un formulaire en C #?

J'ai un formulaire principal (appelons-le frmHireQuote) qui est un enfant d'un formulaire principal MDI (frmMainMDI), qui affiche un autre formulaire (frmImportContact) via ShowDialog () lorsqu'un clic est effectué sur un bouton.

Lorsque l'utilisateur clique sur 'OK' sur frmImportContact, je souhaite transmettre quelques variables de chaîne à des zones de texte sur frmHireQuote.

Notez qu'il peut y avoir plusieurs instances de frmHireQuote. Il est évidemment important que je revienne à l'instance qui a appelé cette instance de frmImportContact.

Quelle est la meilleure méthode pour faire cela?

169
Jez Clark

Créez des propriétés publiques sur votre sous-formulaire

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

puis placez-le dans votre sous-formulaire

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

Puis dans votre frmHireQuote formulaire , lorsque vous ouvrez le sous-formulaire

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

De plus, si vous souhaitez annuler le sous-formulaire , vous pouvez simplement ajouter un bouton au formulaire et définir son DialogResult to Cancel et vous pouvez également définir la propriété CancelButton du formulaire sur ledit bouton - ceci permettra à la touche d'échappement d'annuler le formulaire.

335
Richard Friend

Je crée normalement une méthode statique sur formulaire/dialogue, que je peux appeler. Cela renvoie la réussite (bouton OK) ou l'échec, ainsi que les valeurs à renseigner.

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


 }

Et sur le formulaire:

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

Pour appeler votre formulaire

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

J'ai trouvé un autre petit problème avec ce code ... ou du moins c'était problématique lorsque j'ai essayé de le mettre en œuvre.

Les boutons de frmMain ne renvoient pas de valeur compatible. À l’aide de VS2010, j’ai ajouté ce qui suit et tout a bien fonctionné.

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

Après avoir ajouté les deux valeurs de bouton, la boîte de dialogue a bien fonctionné! Merci pour l'exemple, ça m'a vraiment aidé.

6
DaveHelton

Je viens de mettre quelque chose dans le constructeur par référence, afin que le sous-formulaire puisse changer sa valeur et que le formulaire principal puisse obtenir un objet nouveau ou modifié à partir du sous-formulaire.

1
SerG

Si vous souhaitez transmettre des données à form2 de form1 sans passer comme une nouvelle form(sting "data");

Faire comme ça dans la forme 1

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

en forme 2 ajouter

public string ReturnValue1 { get; set; }

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

Vous pouvez aussi utiliser la valeur dans form1 comme si vous voulez échanger quelque chose dans form1

juste en forme1

textbox.Text =form2.ReturnValue1
0
Matas Lesinskas

Vous devez d’abord définir l’attribut dans form2 (enfant) et le mettre à jour dans form2 ainsi que depuis form1 (parent):

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

Appel de form2 (enfant) à partir de form1 (parent):

  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
Wajid khan

Je soulève un événement dans le formulaire en définissant la valeur et je m'inscris à cet événement dans le (s) formulaire (s) devant traiter le changement de valeur.

0
Edward Miller

les délégués sont la meilleure option pour envoyer des données d'un formulaire à un autre.

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
Sayed idrees

J'utilise beaucoup MDI, je l'aime beaucoup plus (où il peut être utilisé) que plusieurs formes flottantes.

Mais pour en tirer le meilleur parti, vous devez maîtriser vos propres événements. Cela rend la vie tellement plus facile pour vous.

Un exemple squelettique.

Avoir vos propres types d'interruption,

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

Ensuite, votre propre type 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; }

}

Puis utilisez le délégué dans votre espace de noms, mais en dehors d'une classe

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

Désormais, soit manuellement, soit à l'aide de l'interface graphique, demandez à MDIparent de répondre aux événements des formulaires enfants.

Mais avec vos owr Args, vous pouvez réduire cela à une seule fonction. et vous pouvez avoir une disposition pour interrompre les interruptions, ce qui est bon pour le débogage, mais peut aussi être utile autrement.

Il suffit que tous vos codes d’événement mdiparents pointent vers une fonction,

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

Un simple mécanisme de commutation suffit généralement à transmettre les événements aux formulaires appropriés.

0
Bob

Tout ce dont vous avez besoin est d’ajouter le format "d", comme ceci:

private void NewAdmin_Form3_Load_1(object sender, EventArgs e)
{
    DateTime today = DateTime.Today;
    DateTime DateOnly = today.Date;
    DateTime answer = DateOnly.AddDays(90);
    ExitDateAdmin.Text = answer.Date.ToString("d");
}      
0
Jimmy Oku