我有一个父母表格,其中包含带有名字,姓氏等的“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。
我的问题是我宣布一个新的frmWWCModuleHost而不是将ref传递给现有的?我对此的理解仍然很弱。
我通过执行以下操作“解决”了这个问题:在我声明子表单的父表单上,我将 this 作为参数传递。然后在子窗体的构造函数中我添加了_frmWWCModuleHost = m_parent;我的父窗体上有一个UpdateHUD()方法,我从子窗口的_CellClick事件中调用它。
现在重新解释我的问题;这样做有什么明显的错误吗?
答案 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,并且您不必公开任何内容。
我发现这种方法比引发和捕获事件更容易实现,并且它允许您将父类的内部保持在内部。