简体   繁体   English

如何从C#中的表单返回值?

[英]How to return a value from a Form in C#?

I have a main form (let's call it frmHireQuote) that is a child of a main MDI form (frmMainMDI), that shows another form (frmImportContact) via ShowDialog() when a button is clicked. 我有一个主窗体(我们称其为frmHireQuote),它是MDI主窗体(frmMainMDI)的子窗体,单击按钮时通过ShowDialog()显示了另一个窗体(frmImportContact)。

When the user clicks the 'OK' on frmImportContact, I want to pass a few string variables back to some text boxes on frmHireQuote. 当用户单击frmImportContact上的“确定”时,我想将一些字符串变量传递回frmHireQuote上的某些文本框。

Note that there could be multiple instances of frmHireQuote, it's obviously important that I get back to the instance that called this instance of frmImportContact. 请注意,可能有多个frmHireQuote实例,很重要的一点是,我要回到调用此实例frmImportContact的实例。

What's the best method of doing this? 最好的方法是什么?

Create some public Properties on your sub-form like so 像这样在子表单上创建一些公共属性

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

then set this inside your sub-form ok button click handler 然后在您的子表单“确定”按钮单击处理程序中进行设置

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

Then in your frmHireQuote form , when you open the sub-form 然后在您的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 if you wish to cancel out of the sub-form you can just add a button to the form and set its DialogResult to Cancel and you can also set the CancelButton property of the form to said button - this will enable the escape key to cancel out of the form. 另外,如果您希望从子表单中取消,则只需在表单中添加一个按钮并将其DialogResult设置为Cancel ,还可以将表单的CancelButton属性设置为所述按钮-这将使转义键能够取消形式不对

I normally create a static method on form/dialog, that I can call. 我通常在窗体/对话框上创建一个可以调用的静态方法。 This returns the success (OK-button) or failure, along with the values that needs to be filled in. 这将返回成功(确定按钮)或失败,以及需要填写的值。

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


 }

And on the form: 并在表格上:

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

To call your form; 打电话给你的表格;

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

Found another small problem with this code... or at least it was problematic when I tried to implement it. 使用此代码发现了另一个小问题...或者至少在我尝试实现它时出现了问题。

The buttons in frmMain do not return a compatible value, using VS2010 I added the following and everything started working fine. 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;
     }
}

After adding the two button values, the dialog worked great! 添加两个按钮值后,该对话框效果很好! Thanks for the example, it really helped. 感谢您的示例,它确实有所帮助。

我只是通过引用将一些东西放入构造函数中,所以子窗体可以更改其值,主窗体可以从子窗体中获取新对象或修改后的对象。

I use MDI quite a lot, I like it much more (where it can be used) than multiple floating forms. 我使用MDI的次数很多,与多种浮动形式相比,我更喜欢MDI(可以使用的地方)。

But to get the best from it you need to get to grips with your own events. 但是要从中获得最好的收益,您需要掌握自己的事件。 It makes life so much easier for you. 它使您的生活变得更加轻松。

A skeletal example. 一个骨架的例子。

Have your own interupt types, 有自己的中断类型

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

Then your own Args 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; }

}

Then use the delegate within your namespace, but outside of a class 然后在您的名称空间中但在类外部使用委托

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

Now either manually or using the GUI, have the MDIparent respond to the events of the child forms. 现在,无论是手动还是使用GUI,都可以让MDIparent响应子窗体的事件。

But with your owr Args, you can reduce this to a single function. 但是使用owr Args,您可以将其简化为一个函数。 and you can have provision to interupt the interupts, good for debugging, but can be usefull in other ways too. 并且您可以提供对中断的中断,这对于调试非常有用,但是在其他方面也可能有用。

Just have al of your mdiparent event codes point to the one function, 只要让您的所有中间事件代码都指向一个函数,

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

A simple switch mechanism is usually enough to pass events on to appropriate forms. 一个简单的切换机制通常足以将事件传递给适当的形式。

If you want to pass data to form2 from form1 without passing like new form(sting "data"); 如果您想将数据从form1传递到form2而不像新form(sting "data");那样传递form(sting "data");

Do like that in form 1 在表格1中这样做

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

in form 2 add 在表格2中添加

public string ReturnValue1 { get; set; }

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

Also you can use value in form1 like this if you want to swap something in form1 如果您想在form1交换内容,也可以在form1使用值

just in form1 只是在form1

textbox.Text =form2.ReturnValue1

First you have to define attribute in form2(child) you will update this attribute in form2 and also from form1(parent) : 首先,您必须在form2(child)中定义属性,然后在form2中也从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";
 }

Calling of form2(child) from form1(parent): 从form1(父级)调用form2(子级):

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

我以设置值的形式引发事件,并以需要处理值更改的形式订阅该事件。

delegates are the best option for sending data from one form to another. 代表是将数据从一种形式发送到另一种形式的最佳选择。

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

All you need is to add "d" format, like this : 您需要添加“ d”格式,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM