tags:

views:

66

answers:

4

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?

+2  A: 

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

Looks like an observer pattern case.

this. __curious_geek
I want to close all the forms but the mainform.
Harikrishna
So register the references of only those forms which need to be closed.
this. __curious_geek
How can I register the references of the forms??
Harikrishna
Is there any code like I can get all the names of the forms those are running ?
Harikrishna
+1  A: 

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();
}
Hans Passant
Thank You Very Much..It works very properly.......great..
Harikrishna
Is there any code like, frmBallloon is shown in btnShow click event of the frmBase and again I want to show frmBase if user clicks on the btnShow of the frmBalloon then there is two copy of the frmBase.I want only one copy.Then how can I alter the form view by clicking on the button.
Harikrishna
I can't fit an answer in a comment box. Start a new thread with that question.
Hans Passant
@nobugz Ok..I have done that..
Harikrishna
+1  A: 

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]

FernandoZ
A: 

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

Beaner