每种形式都应该是封闭的但不是主形式

时间:2009-12-30 05:14:47

标签: c# .net winforms

我有三个名为frmBase(form1),frmGraph(form2)和frmBalloon(form3)的表单。

如果用户单击位于frmBase(form1)上的名为btnShow的按钮,则会打开

frmGraph(form2)。

如果用户点击放置在frmGraph(form2)上的名为btnShow的按钮,则会打开

frmBalloon(form3)。

现在,如果用户点击放在frmGraph(form2)上的名为btnCancel的按钮,或点击放在frmBalloon(form3)上的名为btnCancel的按钮,则除了frmBase(form1)之外,每个打开的表单都应该关闭。

因此,当用户单击form2或form3上的按钮时,除了mainform之外,每个表单都应该被关闭。那么有什么解决方案吗?

4 个答案:

答案 0 :(得分:2)

维护需要在指定事件上关闭的所有表单对象的引用。在需要时在frmBase中创建并调用该函数。如果打开,该功能将负责关闭所有已注册的表格。

  

看起来像observer pattern个案例。

答案 1 :(得分:1)

这不是一个很好的解决方案,Application.OpenForms有点不可靠,但很容易:

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

答案 2 :(得分:1)

观察者模式适用于某些特殊情况。此类场景的观察者模式的更专业版本是EventAggregator模式。事件聚合器模式非常适合此类场景。

简而言之,事件聚合器允许您集中发布/订阅事件。因此,所有订阅者和发布者仅与EventAggregator通信。订阅者订阅事件,发布者命令事件聚合器发布内容。

事件聚合器模式还将每个发布者订阅者彼此分离。这消除了子表单引用父表单的需要。

杰里米·米勒(Jeremy Miller)在他自己制造的驾驶室系列中提供了一个很好的例子。由于我的新会员资格,我无法发布指向网站的链接,只是搜索以下项目。

Martin Fowler的EventAggregator 由Jeremy Miller建立自己的CAB系列(codebetter.com) PRISM中的EventAggregator

这是一个使用C#和泛型编写的简单示例。这绝不是完整的。它只是为了说明一个简化的例子。有关更完整的模式转向Jeremy Millers的例子。

[代码]

//示例自定义事件参数 使用System;

命名空间EventAggregatorPatternDemo {     public class CloseAllFormsEventArgs:EventArgs     {     } }

//示例表单代码 使用系统; 使用System.Collections.Generic; 使用System.ComponentModel; 使用System.Data; 使用System.Drawing; 使用System.Linq; 使用System.Text; 使用System.Windows.Forms;

命名空间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);
    }
}

}

//事件聚合器代码 使用系统; 使用System.Collections.Generic;

命名空间EventAggregatorPatternDemo {     公共接口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);
                }
            }
        }
    }
}

} [/代码]

答案 3 :(得分:0)

您是否考虑过使用静态事件? Here就是一个简单的例子。