【问题标题】:How do I pass a value from a child back to the parent form?如何将值从子窗体传递回父窗体?
【发布时间】:2010-09-21 18:56:01
【问题描述】:

如何将子窗体的值传递回父窗体?我有一个字符串,我想传回给父级。

我使用以下方式启动了孩子:

FormOptions formOptions = new FormOptions();
formOptions.ShowDialog();

【问题讨论】:

    标签: c# .net winforms parent-child


    【解决方案1】:

    FormOptions 上创建一个属性(或方法),比如GetMyResult

    using (FormOptions formOptions = new FormOptions())
    {
        formOptions.ShowDialog();
    
        string result = formOptions.GetMyResult;
    
        // do what ever with result...
    }
    

    【讨论】:

    • 你的解决方案只有在对话框关闭后才有效,如何将消息传递给父窗体并在子窗体仍处于打开状态时返回
    • @Smith 你不能。不是这样。也不希望这样,因为 ShowDialog() 等到 Form 完成
    【解决方案2】:

    如果您只是使用 formOptions 选择单个值然后关闭,Mitch 的建议是一个不错的方法。如果您需要孩子在保持打开状态的同时与父母交流,则可以使用我的示例。

    在你的父窗体中,添加一个子窗体会调用的公共方法,比如

    public void NotifyMe(string s)
    {
        // Do whatever you need to do with the string
    }
    

    接下来,当您需要从父窗口启动子窗口时,请使用以下代码:

    using (FormOptions formOptions = new FormOptions())
    {
        // passing this in ShowDialog will set the .Owner 
        // property of the child form
        formOptions.ShowDialog(this);
    }
    

    在子窗体中,使用此代码将值传递回父窗体:

    ParentForm parent = (ParentForm)this.Owner;
    parent.NotifyMe("whatever");
    

    本示例中的代码更适合用于类似于工具箱窗口的东西,该窗口旨在浮动在主窗体上方。在这种情况下,您将使用 .Show() 而不是 .ShowDialog() 打开子表单(使用 .TopMost = true)。

    这样的设计意味着子窗体与父窗体紧密耦合(因为子窗体必须将其所有者转换为 ParentForm 才能调用其 NotifyMe 方法)。然而,这并不是一件坏事。

    【讨论】:

    • 我试过你的方法,但对我不起作用。这是我在 parent.NotifyMe() 上遇到的错误。你能帮我找出问题所在吗?该函数在父级中是公共的。 System.NullReferenceException 未处理 HResult=-2147467261 Message=对象引用未设置为对象的实例。
    • @shashlearner:我假设您调用的是formOptions.ShowDialog();,而不是我在帖子中指定的formOptions.ShowDialog(this);。如果你没有在调用中传递this,那么子窗体的.Owner 属性将为null,你会得到一个空引用异常。
    • 优秀正是我想要的
    【解决方案3】:

    您也可以创建公共属性。

    // Using and namespace...
    
    public partial class FormOptions : Form
    {
        private string _MyString;    //  Use this
        public string MyString {     //  in 
          get { return _MyString; }  //  .NET
        }                            //  2.0
    
        public string MyString { get; } // In .NET 3.0 or newer
    
        // The rest of the form code
    }
    

    然后你可以得到它:

    FormOptions formOptions = new FormOptions();
    formOptions.ShowDialog();
    
    string myString = formOptions.MyString;
    

    【讨论】:

    • 它的作用相同,只是在方法中插入了一个属性。
    【解决方案4】:

    您还可以在您的子类中创建 ShowDialog 的重载,该重载会获取一个返回结果的 out 参数。

    public partial class FormOptions : Form
    {
      public DialogResult ShowDialog(out string result)
      {
        DialogResult dialogResult = base.ShowDialog();
    
        result = m_Result;
        return dialogResult;
      }
    }
    

    【讨论】:

    • 我喜欢这个。对话框窗口对我来说总是感觉有点奇怪,因为您正在显示一个窗口,然后在它消失后获取它的信息。这种方法显示窗口并一次检索所有信息。
    【解决方案5】:

    使用子窗体的公共属性

    frmOptions {
         public string Result; }
    
    frmMain {
         frmOptions.ShowDialog(); string r = frmOptions.Result; }
    

    使用事件

    frmMain {
         frmOptions.OnResult += new ResultEventHandler(frmMain.frmOptions_Resukt);
         frmOptions.ShowDialog(); }
    

    使用主窗体的公共属性

    frmOptions {
         public frmMain MainForm; MainForm.Result = "result"; }
    
    frmMain {
         public string Result;
         frmOptions.MainForm = this;
         frmOptions.ShowDialog();
         string r = this.Result; }
    

    使用对象 Control.Tag;这对于所有可以包含 System.Object 的控件公共属性都是常见的。您可以将字符串或 MyClass 或 MainForm 放在那里 - 任何东西!

    frmOptions {
         this.Tag = "result": }
    frmMain {
         frmOptions.ShowDialog();
         string r = frmOptions.Tag as string; }
    

    【讨论】:

      【解决方案6】:

      好吧,我刚刚在这里遇到了同样的问题 - 可能有点不同。但是,我认为这就是我解决它的方法:

      1. 在我的父表单中,我声明了没有实例的子表单,例如RefDateSelect myDateFrm; 所以这对我在这个类/表单中的其他方法可用

      2. 接下来,一个方法通过新实例显示孩子:

        myDateFrm = new RefDateSelect();
        myDateFrm.MdiParent = this;
        myDateFrm.Show();
        myDateFrm.Focus();
        
      3. 我的第三种方法(想要孩子的结果)可以随时出现并简单地得到结果:

        PDateEnd = myDateFrm.JustGetDateEnd();
        pDateStart = myDateFrm.JustGetDateStart();`
        

        注意:子方法 JustGetDateStart() 在 CHILD 中是公共的:

        public DateTime JustGetDateStart()
        {
            return DateTime.Parse(this.dtpStart.EditValue.ToString());
        }
        

      我希望这会有所帮助。

      【讨论】:

        【解决方案7】:

        对于 Picrofo EDY

        这取决于您是否使用ShowDialog() 作为显示表单的一种方式并关闭它,您使用关闭按钮而不是this.Close()。表单不会被丢弃或销毁,只会被隐藏,消失后可以进行更改。为了正确关闭它,您将需要 Dispose()Close() 方法。另一方面,如果使用Show()方法并关闭它,表单将被释放,之后无法修改。

        【讨论】:

          【解决方案8】:

          如果您将子窗体显示为模式对话框,您可以使用来自 DialogResult 枚举的值设置子窗体的 DialogResult 属性,这反过来隐藏模式对话框,并将控制权返回给调用窗体。此时,父表单可以访问子表单的数据以获取所需的信息。

          有关更多信息,请查看此链接: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult(v=vs.110).aspx

          【讨论】:

            【解决方案9】:

            我遇到了同样的问题,我就这样解决了,这里是新手一步一步的指导

            首先在表单类的顶部创建子表单的对象,然后将该对象用于子表单的每个操作,例如显示子表单并从中读取值。

            例子

            namespace ParentChild
            {
               // Parent Form Class
                public partial class ParentForm : Form
                {
                    // Forms Objects
                    ChildForm child_obj = new ChildForm();
            
            
                    // Show Child Forrm
                    private void ShowChildForm_Click(object sender, EventArgs e)
                    {
                        child_obj.ShowDialog();
                    }
            
                   // Read Data from Child Form 
                    private void ReadChildFormData_Click(object sender, EventArgs e)
                    {
                        int ChildData = child_obj.child_value;  // it will have 12345
                    }
            
               }  // parent form class end point
            
            
               // Child Form Class
                public partial class ChildForm : Form
                {
            
                    public int child_value = 0;   //  variable where we will store value to be read by parent form  
            
                    // save something into child_value  variable and close child form 
                    private void SaveData_Click(object sender, EventArgs e)
                    {
                        child_value = 12345;   // save 12345 value to variable
                        this.Close();  // close child form
                    }
            
               }  // child form class end point
            
            
            }  // name space end point
            

            【讨论】:

              【解决方案10】:

              这里有很多剥猫皮的方法,@Mitch's suggestion 是一个好方法。如果您希望客户端表单有更多的“控制”,您可能希望在创建时将父级的实例传递给子级,然后您可以在子级上调用任何公共父级方法。

              【讨论】:

              • 我更喜欢子表单,尽可能不知道谁在给他们打电话。减少耦合...
              【解决方案11】:

              我认为最简单的方法是使用 Tag 属性 在您的 FormOptions 类中设置您需要传递的 Tag = 值 并在 ShowDialog 方法之后将其读取为

              myvalue x=(myvalue)formoptions.Tag;
              

              【讨论】:

              • 我不想在我可以控制的类上使用标签(即我可以添加属性的地方)。我认为使用具有正确名称和类型的属性更简洁。
              【解决方案12】:

              当您使用ShowDialog()Show() 方法,然后关闭表单时,表单对象不会被完全销毁(关闭!= 销毁)。它会一直活着,只是它处于“关闭”状态,你仍然可以对它做一些事情。

              【讨论】:

              • 我认为你的意思是 Hide()。我真的不认为表单在关闭后能够进行更改,除非您从外部访问它。
              【解决方案13】:

              最快和更灵活的方法是从构造函数将父级传递给子级,如下所示:

              1. 在父窗体中声明一个属性:

                public string MyProperty {get; set;}

              2. 以子形式从父级声明一个属性:

                private ParentForm ParentProperty {get; set;}

              3. 像这样写孩子的构造函数:

                  public ChildForm(ParentForm parent){
                      ParentProperty= parent;
                  }
                
              4. 在子窗体中随处更改父属性的值:

                ParentProperty.MyProperty = "New value";

              完成了。父窗体中的属性MyProperty 已更改。使用此解决方案,您可以更改子窗体中的多个属性。太好吃了,不是吗?!

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-03-25
                • 2016-02-29
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多