繁体   English   中英

如何将对象从form1传递给form2并返回到form1?

[英]How do you pass an object from form1 to form2 and back to form1?

在决定提出这个问题之前,我已经对这个问题进行了一些研究。 我找不到任何帮助我的东西。

我正在用C#为紧凑框架2.0编写一个应用程序。

我需要在form1上实例化一个数据对象,并将该对象传递给form2。 处理form2中的数据对象,然后将该数据传递回form1,以便保存。

我理解表单只是一个对象,我也理解对象是通过引用过去而不是通过值。 我也理解这两种类型之间的区别。 我出于某种原因无法使其发挥作用。

实现这一目标的代码中最好,最干净的方法是什么?

你需要做的是为你的第二个表单创建第二个构造函数,它接受一个对象作为参数......对于我所关心的所有内容,它可以是整个Form1对象实例,然后你可以从中得到你想要的任何东西。 以第二种形式保留此对象,并根据需要对其进行修改。 完成第二个表单后,您的第一个表单将包含该数据,并且您可以在第二个表单关闭后执行“刷新”操作。

public partial class YourSecondForm : Form
{
    object PreserveFromFirstForm;

    public YourSecondForm()
    {
       ... its default Constructor...
    }

    public YourSecondForm( object ParmFromFirstForm ) : this()
    {
       this.PreserveFromFirstForm = ParmFromFirstForm;
    } 

    private void YourSecondFormMethodToManipulate()
    {
       // you would obviously have to type-cast the object as needed
       // but could manipulate whatever you needed for the duration of the second form.
       this.PreserveFromFirstForm.Whatever = "something";
    }


}

我一直很喜欢这个事件模型。 这样,您的表单无需了解其他任何人。 您可以在两种表单使用的某种EventHandler类中设置如下所示的事件。

public delegate void SavingObjectHandler(MyObject obj);
public event SavingObjectHandler SavingObjectEvent;
public void SavingObject(MyObject obj)
{
   if (SavingObjectEvent != null) SavingObjectEvent(obj);
}

那么你的一个表单可以调用SavingObject甚至处理程序,另一个表单可以订阅SavingObjectEvent。 当第一个表单触发事件时,将通知第二个表单执行它需要的处理,然后在操作之后对象将再次可用于第一个表单。

我有一个有趣的解决方案,涉及关闭。 在Form2的构造函数中,需要一个Action<TypeOfThing>对象,每当需要将数据返回到Form1时,调用该Action并将数据传递给它。 例如:

class Form1 : Form
{
    private void SomeFunction()
    {
        TypeOfData data;
        Form2 form2 = new Form2((d) => { data = d; });
        form2.ShowDialog() // or whatever you do with form2

        // After you've definitely got your data object from Form2
        DoStuff(data);
    }
}

class Form2 : Form
{
    private Action<TypeOfData> returnData;
    private TypeOfData data;

    public Form2(Action<TypeOfData> r)
    {
        returnData = r;
    }

    private void SomeFunction()
    {
        // Whenever it comes time to return the data you've collected
        returnData(data);
    }
}

我在以下情况下使用过这个实现:我不得不向用户请求密码,我想用一个对话框进行设置,所以我设计了一个带有文本框的对话框,用户可以输入密码,确定和取消按钮。 在FormClosing上,我通过调用Action返回字符串(他们的密码),我只会将该Form用作对话框,因此我可以确保在代码继续时将变量分配给字符串Form1上。 这样我就不必为密码创建一个属性,这是没有意义的,因为密码只是暂时必需的数据。

像这样的东西,ObservableForm是一个基类,并包含ChangeEvent以进一步灵活:

  public class FormMain : Form 
  {

     private ObServableForm childForm = null;


     public FormMain () {

         this.childForm = new ObservableFormConcreateA(this);
         this.childForm.ChangeEvent += (sender, e) => Application.DoEvents();
     }


     public void Present() {

        this.childForm.Show();
     }



 }



 public class ObservableFormConcreateA ObServableForm
 {

    private Form workItemForm = null;

    private delegate void FormChangedHandler(object source, EventArgs args);

//ToDo: this should go in the superclass
     public event FormChangedHandler ChangeEvent;



     public FormChild(ObServableFormworkItem) {

         this.workItemForm = workItem;


     }   


   public void OnUserActionHandler(object sender, EventArgs e) {

             this.formItemForm.Property = this.txtBoxWhateverValue.Text;

             if(ChangeEvent != null)
                 ChangeEvent(this, //create your args to specify which control/data changes);

   }

}

暂无
暂无

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

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