C# 将数据从子表单发送到父表单文本框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/706326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending Data from child form to Parent Form TextBox
提问by Refracted Paladin
I have a Parent Form that holds a "HUD" with First Name, Last Name, etc. One of the child forms is a Search Form. When the user selects a member from the results that are displayed in a DataGrid I want the pertinent information to fill in the HUD. I created a HUD class with variables for each value and a method called UpdateHUD(). I am unsure how to get this working. I have a reference to the Search Form of the Parent form containing the HUD, like so:
我有一个父表单,其中包含一个带有名字、姓氏等的“HUD”。其中一个子表单是搜索表单。当用户从 DataGrid 中显示的结果中选择一个成员时,我希望将相关信息填充到 HUD 中。我创建了一个 HUD 类,其中包含每个值的变量和一个名为 UpdateHUD() 的方法。我不确定如何让这个工作。我引用了包含 HUD 的父表单的搜索表单,如下所示:
public frmWWCModuleHost _frmWWCModuleHost;
This is the code I use to embed forms. I am not using MDI.
这是我用来嵌入表单的代码。我没有使用 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);
}
Here is the code I am running on Cell Click on the Search Form. This is from before I tried implementing the HUD class.
这是我在 Cell 上运行的代码 单击搜索表单。这是在我尝试实现 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();
}
Thanks in advance!
提前致谢!
~ Patrick
~帕特里克
EDIT
编辑
dgvSearchResults_CellContentClick is now current. When I step through this code it is getting the correct Value here but it is never updating the actual HUD.
dgvSearchResults_CellContentClick 现在是最新的。当我逐步执行此代码时,它会在此处获得正确的值,但它永远不会更新实际的 HUD。
EDIT 2
编辑 2
Is my problem that I am declaring a NEW frmWWCModuleHost instead of passing a ref to the existing? I am still pretty weak in my understanding of this.
我的问题是我声明了一个新的 frmWWCModuleHost 而不是将 ref 传递给现有的?我对这个的理解还是很薄弱的。
EDIT 3
编辑 3
I have "solved" this by doing the following: On the Parent Form where I declare the Child Form I pass thisas a param. Then in the constructor of the child form I added _frmWWCModuleHost = m_parent; I have a UpdateHUD() method on my Parent form and I call it from the _CellClick event on the child.
我通过执行以下操作“解决”了这个问题:在我声明子表单的父表单上,我将其作为参数传递。然后在子窗体的构造函数中我添加了 _frmWWCModuleHost = m_parent; 我的父窗体上有一个 UpdateHUD() 方法,我从子窗体上的 _CellClick 事件中调用它。
Now to rephrase my question; Is there anything glaringly wrong with doing it this way?
现在改写我的问题;这样做有什么明显的错误吗?
采纳答案by Neil Barnwell
When the child form search completes, raise a "SearchCompleted" event. Then anything (including the parent form) can subscribe to that event and retrieve the details.
当子表单搜索完成时,引发“SearchCompleted”事件。然后任何东西(包括父表单)都可以订阅该事件并检索详细信息。
See the following NotepadCode for an example:
有关示例,请参阅以下 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);
}
}
}
回答by casperOne
In .NET, Forms are objects like everything else, so you should think of the problem in those terms.
在 .NET 中,表单和其他所有东西一样都是对象,因此您应该从这些方面考虑问题。
With that, the child form will need access to the parent form. You can provide that by passing the parent form reference to the child form through the constructor, a method, or a field/property (although the constructor makes the most sense).
这样,子表单将需要访问父表单。您可以通过构造函数、方法或字段/属性将父表单引用传递给子表单来提供这一点(尽管构造函数最有意义)。
Then, you can change the values in parent form from the child.
然后,您可以从子级更改父级表单中的值。
HOWEVERI would say this isn't the best idea. Rather, the child should expose an event indicating that the data changed (as well as the mechanism to get that data) and then the parent should subscribe to that event and update itself with the data when it is fired.
然而,我会说这不是最好的主意。相反,孩子应该公开一个事件,表明数据发生了变化(以及获取该数据的机制),然后父母应该订阅该事件并在它被触发时用数据更新自己。
回答by John M Gant
Sometimes in situations like this I'll create a delegate that matches the signature of the method I want to call in the parent class (I think that would be UpdateHUD in your case), and then pass an instance of that delegate (i.e. a reference to UpdateHUD) to the child form (the search form in this case). When the child form is finished accepting input, it invokes the delegate using the data collected on the form.
有时在这种情况下,我会创建一个与我想在父类中调用的方法的签名相匹配的委托(我认为在您的情况下这将是 UpdateHUD),然后传递该委托的一个实例(即引用到 UpdateHUD)到子表单(在这种情况下是搜索表单)。当子表单完成接受输入时,它使用在表单上收集的数据调用委托。
So, say UpdateHUD is a method in the parent form that looks something like this.
所以,假设 UpdateHUD 是父表单中的一个方法,看起来像这样。
private void UpdateHUD(string firstName, string lastName) {
//...
}
You would create a delegate with the same signature, like this.
您将创建一个具有相同签名的委托,如下所示。
public delegate void HUDUpdateHandler(string firstName, string lastName);
Then you would add a HUDUpdateHandler parameter to the constructor of the child form and store it in a private field (for example, this.handler = handler
). When your child form is ready to send its data back, you would invoke the child form's private field (this.handler.Invoke(firstNameTextBox.Text, lastNameTextBox.Text)
, for example). That will invoke UpdateHUD in your parent class using the values from the child class, and you won't have to expose anything.
然后,您将向子窗体的构造函数添加一个 HUDUpdateHandler 参数并将其存储在私有字段中(例如,this.handler = handler
)。当您的子表单准备好发回其数据时,您将调用子表单的私有字段(this.handler.Invoke(firstNameTextBox.Text, lastNameTextBox.Text)
例如)。这将使用来自子类的值在您的父类中调用 UpdateHUD,并且您不必公开任何内容。
I find this approach simpler to implement than raising and catching events, and it allows you to keep the internals of your parent class internal.
我发现这种方法比引发和捕获事件更容易实现,并且它允许您将父类的内部结构保持在内部。