Как вернуть значение из формы в C#?



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



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



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



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

1010   7  

7 ответов:

создайте некоторые общедоступные свойства на вашем суб-форма вот так

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

затем установите это внутри вашего суб-форма ok кнопка нажмите обработчик

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 отменить выход из формы.

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

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

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

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

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

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

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

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

скелетная пример.

есть свои собственные типы interupt,

//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 реагировать на события дочерних форм.

но с помощью 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);

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

если вы хотите передать данные 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

просто в form1

textbox.Text =form2.ReturnValue1

сначала вы должны определить атрибут в 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); 
  }

Comments

    Ничего не найдено.