Passing Data Between 3 Separate WinForms [duplicat

2020-01-29 02:21发布

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

1条回答
Fickle 薄情
2楼-- · 2020-01-29 02:47

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.

查看更多
登录 后发表回答