【问题标题】:Can I make a Form a singleton?我可以将表单设为单例吗?
【发布时间】:2013-01-14 05:23:31
【问题描述】:

我有一个 Visual C# 2010 应用程序,它有一个名为 MainWnd 的主窗体以及其他工具窗口和对话框。我希望其他工具窗口能够与主窗体“对话”,并调用其方法。但这需要MainWnd 的实例,并且由于在任何给定时间只会创建其中一个表单,因此我没有理由枚举MainWnd 的所有实例或查找第一个实例。所以我希望我的主申请表MainWnd 是一个单例,以便其他窗口可以轻松地从中调用代码。

这里是我想做一个单例的主窗体的代码:

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace MyLittleApp
{
    public partial class MainWnd : Form
    {
        public MainWnd()
        {
            InitializeComponent();
        }

        public void SayHello()
        {
            MessageBox.Show("Hello World!");

            // In reality, code that manipulates controls on the form
            // would go here. So this method cannot simply be made static.
        }
    }
}

我希望能够通过另一种形式调用SayHello(),只需编写:

MainWnd.SayHello();

我怎样才能做到这一点?

【问题讨论】:

  • 你不能把它作为一个静态公共方法然后按你说的做吗?
  • 因为它被称为 MainWnd 我希望该表单打开其他表单。在这种情况下,您可以在子表单上使用一个事件,并从那里的 MainWnd 注册一个事件接收器。
  • @ryadavilli 正如我发布的代码中的评论所说,该方法操作表单中的对象,因此它必须有一个实例,因此它不能只是静态的。

标签: c# winforms singleton


【解决方案1】:

您可能会找到一种方法使主窗口成为单例,但这不是实现您想要的结果的最佳方式,也不是使用单例模式的合适情况。

如果所有其他工具窗口/对话框都封装在主窗口中,那么用于通信的更好模式就是事件。

让内部窗口/对话框引发事件以表示主窗口执行某项操作的“请求”。让主窗口订阅这些事件,并通过事件处理程序完成工作。

通过避免单例方法,您可以避免测试单例的困难,以及避免大量显式循环引用,其中不仅主窗口引用了封装的窗口/对话框,而且它们又具有显式引用返回主窗口。

【讨论】:

  • +1 绝对比我想象的要好。感谢您让我看到更好的设计模式:)
【解决方案2】:

见下文。

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace MyLittleApp
{
    public partial class MainWnd : Form
    {
       public static MainWnd Instance;
        public MainWnd()
        {
            Instance = this;
            InitializeComponent();
        }

        public void SayHello()
        {
            MessageBox.Show("Hello World!");

            // In reality, code that manipulates controls on the form
            // would go here. So this method cannot simply be made static.
        }
    }
}

您现在可以通过调用 MainWnd.Instance 在代码中的任何位置使用它 它的所有成员也可供实例使用。

【讨论】:

    【解决方案3】:

    你当然可以这样做。

     public MainWnd Instance = new MainWnd();
    

    然后以MainWnd.Instance.SayHello() 访问。

    替换以下调用

    MainWind instance = new MainWnd();
    

     MainWnd instance = MainWnd.Instance;
    

    我不确定 Visual Studio 设计器在将构造函数设为私有后会有什么反应。 但如果不允许,那将是 Visual Studio 问题,而不是语言/编译器问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 2020-03-30
      相关资源
      最近更新 更多