问题描述
在我在 C# WinForms 领域进行编码期间,我遇到过许多在表单之间传递数据的不同方法的实例.我在一个大型代码库上工作——其中一些方法是由其他人编写的,我随后对其进行了扩展,还有一些是我自己编写的.似乎有两种主要的范式,我对这两种范式都进行了相当轻松的编码.
1.) 在实例化或显示子窗体时将父窗体传递给子窗体.例如:
ChildForm.Instance = new ChildForm(this);- 或者 -ChildForm.Instance = new ChildForm();ChildForm.Instance.Show(this.TopLevelControl);
这允许子级从父级获取信息,并允许父级调用子级的方法.请耐心等待——我确实意识到这打破了很多范式,并且是不好"的做法——请记住,我在维护一个更大的代码库期间遇到了很多这样的情况,我需要对其进行增量调整无需进行完整的重构.
2.) 使用事件委托来允许在父表单和子表单之间传输数据.据我所知,这仍然需要父表单在生成孩子时建立此事件.例如:
在父级内:
childForm = new ChildForm(this);DataRead += new DataReadEventHandler(childForm.ChildForm_DataRead);
在孩子内:
public void ChildForm_DataRead(Data data){if (InvokeRequired){调用(新 MethodInvoker(delegate() { ChildForm_DataRead(data); }));}别的//做一点事}
这种性质的东西.现在,我仍然不是 C# WinForms 的强大编码人员,但我确实意识到从设计角度来看,事件/消息传递方法可能更好".
<小时>现在,这是我的问题.
为了命名,我有一个主窗体:ParentForm.ParentForm 目前使用后一种形式的消息传递(har har!)将数据传递给,比如说,FirstChildForm.本质上,ParentForm一旦获取数据,就会触发DataReadEventHandler,将数据从ParentForm传递给FirstChildForm.
没问题.
现在,我/也/有一个从 ParentForm 生成的表单,称为 SecondChildForm.注意:这不是 ChildForm 的另一个实例……它是完全不同的形式.这里有一个问题——当 SecondChildForm 上的数据更新时,我希望将这些数据传递给 FirstChildForm.这似乎是一个简单的想法,尽管我在思考如何实现它时遇到了一些困难.我能想到的只是为每个孩子从 ParentForm 设置唯一的事件处理程序,然后让 SecondChildFrom 的事件处理程序触发 FirstChildForm 的 ParentForm 事件处理程序......这听起来非常令人费解,因为数据(非平凡的大小,我可能会添加),必须首先从 SecondChildForm 传递到 ParentForm,然后从 ParentForm 传递到 FirstChildForm.
有更好的方法吗?
另外,我真的不想这么说,但是,老实说,在这个高度封闭的应用程序中,如果正确的方法非常复杂,我可以为了简单而打破范式(尽管如此,我还是会在正确重构的未来——是的,我实际上/am/能够做到这一点!).
干杯!
-卡达杰
所以数据首先在第二个孩子上生成,所以在那个表单上,我们需要一个可以触发的事件来提供该数据:
p>
public class SecondChildForm : Form{公共事件操作<MyData>发生了一些事;//其他代码,包括在某个时间点触发事件的代码}
然后我们有了第一个孩子,它有一些需要调用的方法来传递该数据:
公共类 FirstChildForm : Form{公共无效WhenSomethingHappens(MyData数据){//用数据做事}}
最后我们有了创建两个表单并连接适当事件处理程序的主表单:
public class ParentForm : Form{公共父窗体(){FirstChildForm firstChild = new FirstChildForm();SecondChildForm secondChild = new SecondChildForm();secondChild.SomethingHappened += firstChild.WhenSomethingHappens;//显示表格并做其他事情}}
瞧.
请注意,使用这种模式,每个孩子都不知道他们父母的任何事情.它们通过事件公开父级所需的信息,并允许父级通过公共方法影响它,但它们不知道也不关心哪些类正在使用它们.父级确实知道它的子类型;它适合拥有特定子类型的实例并直接操纵它的公共成员(但不是它的内部控件,它不应该是公共的).
Throughout my time coding in the realm of C# WinForms, I have had many instances in which I have come across different methods of passing data between forms. I work on a large codebase -- some of these methods were written by others, which I subsequently extended, and others were written by myself. It seems there are two main paradigms, both of which I have coded rather comfortably.
1.) Pass the parent form to the child when instantiating or showing the child form. For example:
ChildForm.Instance = new ChildForm(this);
--Or--
ChildForm.Instance = new ChildForm();
ChildForm.Instance.Show(this.TopLevelControl);
This allows the child to pull information from the parent, as well as allows the parent to call methods on the child. Bear with me for a moment -- I do realize that this breaks so many paradigms, and is "bad" practice -- remember, I'm encountering much of this during maintenance of a larger codebase to which I am required to make incremental adjustments without doing a complete refactoring.
2.) Use an event delegate to allow for data to be transferred between parent and child forms. To the best of my knowledge, this still requires that the parent form establish this event when spawning the child. For example:
Within parent:
childForm = new ChildForm(this);
DataRead += new DataReadEventHandler(childForm.ChildForm_DataRead);
Within child:
public void ChildForm_DataRead(Data data)
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(delegate() { ChildForm_DataRead(data); }));
}
else
//do something
}
Something of this nature. Now, I'm still not a strong coder in C# WinForms, but I do realize that the event/messaging approach is probably "better" from a design perspective.
Now, here is my question.
I have a main form, for naming's sake: ParentForm. ParentForm currently utilizes the latter form (har har!) of messaging to pass data to, let's say, FirstChildForm. Essentially, once ParentForm acquires data, it triggers the DataReadEventHandler, and data is passed from ParentForm to FirstChildForm.
No problem.
Now, I /also/ have a form spawned from ParentForm, called SecondChildForm. NB: this is not another instance of ChildForm... it's an entirely different form. Here's the catch -- when data updates on SecondChildForm, I want to have this data passed to FirstChildForm. It seems like such a simple idea, although I'm having some difficulty wrapping my head around how to implement it. All I can think of is setting up unique event handlers from ParentForm for each child, and having the event handler from SecondChildFrom then trigger ParentForm's event handler for FirstChildForm... this sounds terribly convoluted, as the data (of non-trivial size, I might add), must be first passed from SecondChildForm to ParentForm, and subsequently from ParentForm to FirstChildForm.
Is there a better way of doing this?
Also, I'd really prefer not to say this, but, to be perfectly honest, in this highly closed application, I'm OK with breaking paradigm for simplicity if the proper method is highly convoluted (would nevertheless allocate time in the future for proper refactoring -- yes, I actually /am/ able to do this!).
Cheers!
-Kadaj
So the data is first generated on the second child, so on that form we'll want an event that can be triggered that can provide that data:
public class SecondChildForm : Form
{
public event Action<MyData> SomethingHappened;
//Other code, including code that fires the event at some point
}
Then we have the first child which has some method that needs to be called passing in that data:
public class FirstChildForm : Form
{
public void WhenSomethingHappens(MyData data)
{
//Do stuff with data
}
}
Finally we have the main form that creates both of the forms and wires up the appropriate event handlers:
public class ParentForm : Form
{
public ParentForm()
{
FirstChildForm firstChild = new FirstChildForm();
SecondChildForm secondChild = new SecondChildForm();
secondChild.SomethingHappened += firstChild.WhenSomethingHappens;
//show forms and do other stuff
}
}
Voila.
Note that using this pattern each child doesn't know anything about their parent. They expose information needed by the parent through events, and they allow the parent to affect it through public methods, but they don't know or care which class(es) are using them. The parent does know about it's child type; it's appropriate for it to have an instance of the specific child type and to manipulate it's public members (but not its inner controls, which shouldn't be public) directly.
这篇关于在 3 个单独的 WinForms 之间传递数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!