Harikrishna
Harikrishna

Reputation: 4305

every forms should be closed but not mainform

I have three forms named frmBase(form1),frmGraph(form2) and frmBalloon(form3).

frmGraph(form2) opens if the user clicks on the button named btnShow placed on frmBase(form1).

frmBalloon(form3) opens if the user clicks on the button named btnShow placed on frmGraph(form2).

Now if the user clicks on the button named btnCancel placed on the frmGraph(form2) OR clicks on the button named btnCancel placed on the frmBalloon(form3) every form that is open should be closed except frmBase(form1).

So, every forms should be closed except mainform when user clicks on the button placed on the form2 or form3. So for that is there any solution?

Upvotes: 0

Views: 669

Answers (4)

this. __curious_geek
this. __curious_geek

Reputation: 43207

Maintain references of all form objects that needs to be closed on designated event. Create and Call the function in frmBase whenever needed. The function will be responsible to close all registered forms if open.

Looks like an observer pattern case.

Upvotes: 2

FernandoZ
FernandoZ

Reputation: 438

Observer pattern is appropriate with some specializaiton. A more specialized version of the observer pattern for this type of scenario is the EventAggregator pattern. The event aggregator pattern is ideal for this type of scenario.

In short the event aggregator allows you to centralize the publishing/subscription of events. Therefore all subscribers and publishers talk only to the EventAggregator. Subscribers subscribe to events and publishers command the event aggregator to publish something.

The event aggregator pattern also decouples each publisher subscriber from each other. This eliminates the need for the child forms to reference the parent forms.

Jeremy Miller provides a good example in his Build Your Own Cab series. Due to my new membership I cant post the links to the sites but just a do a search for the following items.

EventAggregator by Martin Fowler Build Your Own CAB series by Jeremy Miller (codebetter.com) EventAggregator in PRISM

Here is a simple example I cooked up using C# and generics. This is by no means complete. It is just to illustrate a simplified example. For a more complete patter turn to Jeremy Millers example.

[code]

//Sample Custom Event args using System;

namespace EventAggregatorPatternDemo { public class CloseAllFormsEventArgs : EventArgs { } }

//Sample Form Code using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;

namespace EventAggregatorPatternDemo { public partial class GraphForm : Form, IListener { public GraphForm() { InitializeComponent(); }

    private void GraphForm_Load(object sender, EventArgs e)
    {
        EventAggregator.GetTheEventAggregator().Subscribe<CloseAllFormsEventArgs>(this);
    }

    public void Handle<TEventArgs>(TEventArgs e)
    {
        if (e.GetType() == typeof(CloseAllFormsEventArgs))
        {
            this.Close();
        }
    }

    private void btnCloseAll_Click(object sender, EventArgs e)
    {
        EventAggregator.GetTheEventAggregator().Publish(this, new CloseAllFormsEventArgs());
    }

    private void GraphForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        EventAggregator.GetTheEventAggregator().CancelSubscription<CloseAllFormsEventArgs>(this);
    }
}

}

//Event Aggregator code using System; using System.Collections.Generic;

namespace EventAggregatorPatternDemo { public interface IListener { void Handle(TEventArgs e); }

public class EventAggregator
{
    static EventAggregator _TheEventAggregator;

    readonly Dictionary<Type, List<IListener>> _listeners;

    private EventAggregator()
    {
        _listeners = new Dictionary<Type, List<IListener>>();
    }

    public static EventAggregator GetTheEventAggregator()
    {
        if(_TheEventAggregator == null)
        {
            _TheEventAggregator = new EventAggregator();
        }

        return _TheEventAggregator;
    }

    public void Publish<TEventArgs>(object sender, TEventArgs e)
    {
        if(_listeners.ContainsKey(e.GetType()))
        {
            var listOfSubscribers = _listeners[e.GetType()];

            for(int i = listOfSubscribers.Count - 1; i > -1; i--)
            {
                listOfSubscribers[i].Handle(e);
            }
        }
    }

    public void Subscribe<TEventArgs>(IListener listener)
    {
        if(_listeners.ContainsKey(typeof(TEventArgs)))
        {
            _listeners[typeof(TEventArgs)].Add(listener);
        }
        else
        {
            List<IListener> newListenerList = new List<IListener>();
            newListenerList.Add(listener);

            _listeners.Add(typeof(TEventArgs), newListenerList);
        }
    }

    //Cancels all subscriptions
    public void CancelSubscription<TEventArgs>(IListener listener)
    {
        Type eventArgsType = typeof(TEventArgs);

        if (_listeners.ContainsKey(eventArgsType))
        {
            //Remove from the end
            for (int i = _listeners[eventArgsType].Count-1; i > -1; i-- )
            {
                //If the objects are the same 
                if(ReferenceEquals(_listeners[eventArgsType][i], listener))
                {
                    _listeners[eventArgsType].RemoveAt(i);
                }
            }
        }
    }
}

} [/code]

Upvotes: 1

jac
jac

Reputation: 9726

Have you thought about using a static event? Here is a simple example.

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 941465

It is not a great solution, Application.OpenForms is a bit unreliable, but easy:

public static void CloseAllFormsButMain() {
  for (int ix = Application.OpenForms.Count - 1; ix > 0; --ix)
    Application.OpenForms[ix].Close();
}

Upvotes: 1

Related Questions