【问题标题】:How do you pass an object from form1 to form2 and back to form1?如何将对象从 form1 传递到 form2 并返回到 form1?
【发布时间】:2011-02-03 15:06:25
【问题描述】:

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

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

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

我明白表单只是一个对象,我也明白对象是通过引用而不是通过值过去的。我也理解这两种类型的区别。由于某种原因,我无法让它工作。

实现这一目标的最佳、最简洁的代码方式是什么?

【问题讨论】:

标签: c# winforms


【解决方案1】:

你需要做的是为你的第二个表单创建第二个构造函数,它接受一个对象作为参数......我只关心它可能是整个 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";
    }


}

【讨论】:

  • 补充一点:从第一个表单开始,您将创建第二个表单的实例,然后使用mySecondForm.ShowDialog() 显示它。由于您通过引用传递参数对象,因此您可以在第二种形式中随意更改它,当 ShowDialog() 调用返回时,这些更改将保留在对象中。
  • @MusiGenesis .. 好点,我完全错过了对基于 DIALOG 的第二种形式的调用。谢谢你的收获。
  • 哇。就这么简单。你的例子和解释是正确的。谢谢。
【解决方案2】:

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

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

然后您的一个表单可以调用 SavingObject 事件处理程序,而另一个表单可以订阅 SavingObjectEvent。当第一个表单触发事件时,将通知第二个表单进行所需的处理,然后在操作后对象将再次可供第一个表单使用。

【讨论】:

    【解决方案3】:

    类似这样的东西,其中 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);
    
       }
    

    }

    【讨论】:

    • 哇,我以前从未在 LINQ 语句中看到过Application.DoEvents()。 :)
    【解决方案4】:

    我为您提供了一个有趣的解决方案,包括关闭。在 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 用作对话框,因此我可以确定在代码继续时变量将被分配给字符串表格 1。这样我就不必为 Password 创建一个属性,这没有任何意义,因为密码只是暂时需要的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-30
      • 2015-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 2011-05-11
      相关资源
      最近更新 更多