2

I am new to .Net Winforms, i generally work on either console apps or MVC.

I am developing a MDI WinForms application, and if I make a change in one (any) window, I need all other open MDI forms to refresh when the change has been made so they can also show the updated data.

How can this be achieved - In my old Delphi (v3) days, you used to "publish" a WM_USER type message and each form would have a "subscriber handler" that would then take the required action but that was a long time ago.

All the forms are slight variations of the data and a change in one form can affect the data in the others..

TYIA

Chris Hammond
  • 2,064
  • 5
  • 27
  • 53
  • Are all the Forms of the same type (if so, you can take reference from here: http://stackoverflow.com/questions/4646705/how-can-i-loop-through-all-the-open-instances-of-a-particular-form and https://msdn.microsoft.com/en-us/library/system.windows.forms.application.openforms(v=vs.110).aspx)? Using that you can loop over all open forms, and call a Refresh() method (declare it as public). – Keyur PATEL Feb 08 '17 at 07:52
  • No, the forms are not multiple instances of the same form, they are all slightly different.. but it would work in principle... Ideally.. I would only want to refresh forms if it uses the __type__ of data that's changed (e.g. all forms that are showing some sort of employee data) – Chris Hammond Feb 08 '17 at 08:00
  • 2
    Add an event to your MDI parent form, all children can subscribe it. – Hans Passant Feb 08 '17 at 08:12

2 Answers2

1

You can still use the windows messaging infrastructure. Explained here and here.

LoekD
  • 11,402
  • 17
  • 27
1

You need an event system between children and parent, which can be accomplished as follows:

  • Create a base class for your child forms that contains an event to be raised when any data on the form is changed. Let's call it FormChanged event.
  • Add an event to the Parent form to notify all children. Let's call it ChildFormChanged event.
  • Upon instantiation of each child form, have the parent form subscribe to the FormChanged event of the child, AND have the new child form subscribe to the ChildFormChanged event of the parent form.
  • The event handler for the FormChanged event in the parent form is just a pass-through function, that in turn raises the ChildFormChanged event, passing the information received from the child form causing the event to fire.
  • The ChildFormChanged event can be handled in the base class for child forms via a virtual event handler (to handle generic items) that can be overridden in each child class (to handle specifics of each child form).

I wrote and commented an example app in C# and posted it on Github. Here's the relevant code:

Base child Form:

    public event EventHandler<EventArgs> FormChanged;

    public virtual void ProcessChange(object sender, EventArgs e)
    {
        if((sender as Form) != this)
        {
            //Handle change
        }
    }

    protected void NotifyParent() => FormChanged?.Invoke(this, EventArgs.Empty);

Parent form:

    public event EventHandler ChildFormChanged;

    public void NotifyAllChildren(object sender, EventArgs e)
        => ChildFormChanged?.Invoke(sender, e);

    //Child form creation function
    private void createNewFormToolStripMenuItem_Click(object sender, EventArgs e)
    {

        MDIChildBase newChild = new MDIChild(); //Can be different child forms
        newChild.MdiParent = this;

        //Parent-child event subscription
        newChild.FormChanged += NotifyAllChildren;
        ChildFormChanged += newChild.ProcessChange;

        newChild.Show();
    }

Every child form must call base.NotifyParent(); once any changes occur that you want to propagate to other child forms.

CoolBots
  • 4,770
  • 2
  • 16
  • 30
  • I am surmising that I could add information to the EventArgs (or a custom one) to specify type of change (employee / stock ) and then the react as appropriate in the child form – Chris Hammond Feb 08 '17 at 09:45
  • @ChrisHammond, absolutely, or declare your own delegate - I used `EventHandler` to make the example quick and easy to read, as many readers are familiar with this delegate. – CoolBots Feb 08 '17 at 09:55