Winform单例模式之牛刀小试

今天winform开发时,有一个需求:点击一个button,弹出一个窗体,显示相关信息,此时再点击button,就不再创建窗体,这里有两种方式解决:

  1. 弹出窗体不关闭,无法操作主窗体
  2. 使用单例模式

    这里使用第二种方法:单例模式(详见百度
    具体代码如下:

public partial class About : Form
{
    public static About instance { get; set; }
    private About()
    {
        InitializeComponent();
    }
    public static About GetInstance()
    {
        if (instance == null)
        {
            instance = new About();
        }
        return instance;
    }
}

调用

About about=About.GetInstance();
about.Show();

这样就实现了同时只能打开一个窗体,又能同时操作其他窗体。

But,实际操作之后,会出现这个错误:
无法访问已释放的对象
这是因为在关闭窗体后,这个对象虽然可能还没被GC回收,但是IsDisposed已经被置为true,已经被视为释放了,这就造成无法访问。
这时可以通过监听Disposed事件来重新分配对象内存。

代码:

public partial class About : Form
{
    public static About instance { get; set; }
    private About()
    {
        InitializeComponent();
    }
    public static About GetInstance()
    {
        if (instance == null)
        {
            instance = new About();
        }
        instance.Disposed+=new EventHandler(instance_Disposed);
        return instance;
    }
    static void instance_Disposed(object sender,EventArgs e)
    {
        instance = null;
    }
}
WinForm 应用中,实现单例模式的核心是确保在应用程序的生命周期内,某个类只被实例化一次,从而让整个应用程序中仅有一个该类的实例化对象。常见的实现方法是使用私有静态实例和公共访问点来控制实例的创建和访问。 ### 实现方法 在 WinForm 应用里,显示窗体通常有 `Show()` 和 `ShowDialog()` 两种方法。`Show()` 方法在多次点击按钮时会显示多个当前窗体,操作不便;`ShowDialog()` 方法显示窗体后,只能对当前窗体操作,直至其关闭,用户体验不佳。若每次点击按钮都使用相同的实例化对象,就能只产生一个窗体,再使用 `Show()` 方法显示窗体则不会影响其他窗体操作 [^1]。 ### 示例代码 以下是一个简单的 WinForm 单例模式示例代码: ```csharp public partial class MainForm : Form { // 私有静态实例 private static MainForm _instance; // 私有构造函数 private MainForm() { InitializeComponent(); } // 公共访问点 public static MainForm Instance { get { if (_instance == null || _instance.IsDisposed) { _instance = new MainForm(); } return _instance; } } } // 使用方式 var mainForm = MainForm.Instance; mainForm.Show(); ``` 在上述示例中,`MainForm` 类的构造函数被设为私有,这保证了该类不能在外部被直接实例化。同时,通过 `Instance` 属性来控制实例的创建和访问,若实例不存在或已被销毁,就会创建一个新的实例,否则返回现有的实例 [^4]。 另外,在 WinForm 中使用 MySQL 数据库时,也可以采用单例模式来管理数据库连接。以下是一个在按钮点击事件中使用 MySQL 单例模式的示例: ```csharp // 在按钮点击事件中使用 private void btnLoadUsers_Click(object sender, EventArgs e) { string sql = "SELECT id, username FROM users"; WinFormMySqlDb.Instance.ExecuteQuery(sql, reader => { dataGridViewUsers.Rows.Clear(); while (reader.Read()) { dataGridViewUsers.Rows.Add( reader["id"].ToString(), reader["username"].ToString()); } }, this); } ``` 此示例中,`WinFormMySqlDb` 类使用单例模式,通过 `Instance` 属性获取数据库实例并执行查询操作 [^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值