将数据从子表单发送到父表单TextBox

时间:2009-04-01 16:23:06

标签: c# winforms .net-3.5

我有一个父母表格,其中包含带有名字,姓氏等的“HUD”。其中一个子表单是搜索表单。当用户从DataGrid中显示的结果中选择一个成员时,我希望相关信息填写HUD。我创建了一个HUD类,其中包含每个值的变量和一个名为UpdateHUD()的方法。我不确定如何使这个工作。我引用了包含HUD的父表单的搜索表单,如下所示:

public frmWWCModuleHost _frmWWCModuleHost;

这是我用来嵌入表单的代码。我没有使用MDI。

 public static void ShowFormInContainerControl(Control ctl, Form frm)
    {
        frm.TopLevel = false;
        frm.FormBorderStyle = FormBorderStyle.None;
        frm.Dock = DockStyle.Fill;
        frm.Visible = true;
        ctl.Controls.Add(frm);
    }

以下是我在“搜索表单”上单击“单击”时运行的代码。这是在我尝试实现HUD类之前。

private void dgvSearchResults_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        _frmWWCModuleHost = new frmWWCModuleHost();
        _frmWWCModuleHost.tbxHUD_LastName.Text = dgvSearchResults.CurrentRow.Cells[1].FormattedValue.ToString();
        _frmWWCModuleHost.tbxHUD_LastName.Invalidate();
        _frmWWCModuleHost.FormPaint();
    }

提前致谢!

~Patrick


修改


dgvSearchResults_CellContentClick现在是最新的。当我单步执行此代码时,它在此处获得正确的值,但它永远不会更新实际的HUD。


编辑2


我的问题是我宣布一个新的frmWWCModuleHost而不是将ref传递给现有的?我对此的理解仍然很弱。


编辑3


我通过执行以下操作“解决”了这个问题:在我声明子表单的父表单上,我将 this 作为参数传递。然后在子窗体的构造函数中我添加了_frmWWCModuleHost = m_parent;我的父窗体上有一个UpdateHUD()方法,我从子窗口的_CellClick事件中调用它。

现在重新解释我的问题;这样做有什么明显的错误吗?

3 个答案:

答案 0 :(得分:5)

当子表单搜索完成时,引发“SearchCompleted”事件。然后任何东西(包括父表单)都可以订阅该事件并检索详细信息。

有关示例,请参阅以下NotepadCode:

class ParentForm
{
    private readonly ChildForm childForm;

    public ParentForm()
    {
        InitializeComponent();

        childForm = new ChildForm();

        childForm.SearchCompleted += childForm_SearchCompleted;
    }

    private void childForm_SearchCompleted(object sender, SearchCompletedEventArgs e)
    {
        // Update the display
        lblName.Text = e.DataToDisplay;
    }
}

class ChildForm
{
    public event EventHandler<SearchCompletedEventArgs> SearchCompleted;

    private void Search(string query)
    {
        // Do the searching

        OnSearchCompleted(new SearchCompletedEventArgs([arg values]));
    }

    public void OnSearchCompleted(SearchCompletedEventArgs args)
    {
        if (SearchCompleted != null)
        {
            SearchCompleted(this, args);
        }
    }
}

答案 1 :(得分:2)

在.NET中,Forms就像其他所有对象一样,所以你应该用这些术语来思考这个问题。

这样,子表单将需要访问父表单。您可以通过构造函数,方法或字段/属性将父表单引用传递给子表单来提供(尽管构造函数最有意义)。

然后,您可以从子级更改父级表单中的值。

我想说这不是最好的主意。相反,孩子应该公开一个事件,表明数据已经改变(以及获取该数据的机制),然后父母应该订阅该事件并在触发时用数据更新自己。

答案 2 :(得分:2)

有时在这样的情况下,我将创建一个委托,该委托匹配我想在父类中调用的方法的签名(我认为在你的情况下会是UpdateHUD),然后传递该委托的实例(即对子表单的引用(即UpdateHUD)(在本例中为搜索表单)。当子表单完成接受输入时,它将使用表单上收集的数据调用委托。

所以,说UpdateHUD是父表单中看起来像这样的方法。

private void UpdateHUD(string firstName, string lastName) {
    //...
}

您将创建一个具有相同签名的委托,如下所示。

public delegate void HUDUpdateHandler(string firstName, string lastName);

然后,您将HUDUpdateHandler参数添加到子表单的构造函数中,并将其存储在私有字段中(例如,this.handler = handler)。当您的子表单准备好发回其数据时,您将调用子表单的私有字段(例如this.handler.Invoke(firstNameTextBox.Text, lastNameTextBox.Text))。这将使用子类中的值调用父类中的UpdateHUD,并且您不必公开任何内容。

我发现这种方法比引发和捕获事件更容易实现,并且它允许您将父类的内部保持在内部。