单例模式(Winform窗体的实现)
在我的设计模式分类当中,我选择单例模式作为我第一个要写的设计模式,其一,单例模式简单、容易理解让人接受,其二,单例模式很常用,在实际的Winform窗体应用开发中能够带来更好的客户体验。
单例模式的核心是在应用程序的生命周期中只实例化一次当前类,让整个应用整个应用程序中只拥有一个当前类实例化的对象,在Winform应用程序中,我们显示窗体的方法有两种方法:第一种,Show()方法,这种方法当点击多次按钮的时候会显示多个当前的窗体,造成操作不便。第二种,ShowDialog()方法,这种方法显示出窗体之后,我们只能对当前窗体进行操作直到这个窗体关闭之后,用户体验不好。那怎样才能只产生一个窗体,而且不影响对其他窗体的操作?解决这样的问题我们最简单的想法就是如果每次我们单机按钮都使用相同的实例化对象,就只能产生一个窗体了,再使用Show()方法显示窗体就不会影响其他窗体的操作了。
说了这么多,让我们看看怎么在窗体中使用单例模式吧,核心参考代码如下:
public partial class FrmSingleton : Form
{
private static FrmSingleton frm = null;
private FrmSingleton()
{
InitializeComponent();
} public static FrmSingleton CreateInstrance()
{
if (frm == null)
{
frm = new FrmSingleton();
}
return frm;
}
}
FrmSingleton
从上面的代码我们可以看出使用单例模式有三个重要的要点:
(1)构造方法一定要定义成私有的(这样做的好处就是我们只能在当前类里面实例化一个对象,类外面不能实例化,外界想使用的话我们可以给它提供一个静态方法供外界获取)
(2)定义一个私有的数据类型为当前类的变量(用于保证类的实例化对象的唯一性)
(3)定义一个静态的方法用于给外界提供当前类的实例化对象
上面是单例模式使用当中应该注意的地方,定义好了之后,我们就要在主窗体中的button事件中调用它了,具体代码如下:
private void button1_Click(object sender, EventArgs e)
{
FrmSingleton FrmSingleton = FrmSingleton.CreateInstrance();
FrmSingleton.Show();
}
button事件调用
好了,一个简单的单例模式的Demo就写完了,我们运行一下应用程序,多次点击按钮,也只产生一个窗体,是不是很有成就感,但是这个时候一定不要激动太早,当我们关闭当前打开的窗体之后,再次单机按钮则提示我们“无法访问已经释放的内存”,其实也很容易解释,当我们关闭窗体时,C#默认的垃圾回收机制会回收我们的frm对象,但此时frm对象并不为null,当我们再次使用frm==null进行判断时,结果是false,返回出去的是释放内存的frm对象,所以造成这样的结果,那么我们怎么做才能避免异常呢,最简单的做法就是在判断frm==null的地方添加一个或运算,判断一下是否已经释放,如果释放了,我们也要进行再次实例化,修改我们刚才的代码,修改后的代码如下:
public partial class FrmSingleton : Form
{
private static FrmSingleton frm = null;
private FrmSingleton()
{
InitializeComponent();
} public static FrmSingleton CreateInstrance()
{
if (frm == null ||frm.IsDisposed)
{
frm = new FrmSingleton();
}
return frm;
}
}
FrmSingleton
这样我们在运行代码,就不会出现我们刚才遇到的问题了,一个简单的单例模式这样才算结束,又可以愉快的玩耍了。
那么问题又来了,假如说我有很多的窗体都要使用单例模式,难道我都要把每个窗体的代码都要修改成那个样子吗,加入窗体多起来的话,那这种方式就会变得很麻烦,那有没有一种简单的方式,能让我们不管增加多少窗体都能很简单的使用我们的单例模式呢?
再次回忆我们构建一个单例模式的三个要点,我们发现,它们的格式基本上没有什么不同,除了里面使用到了不同的类型,对于不同的类型,我们可以很容易想到用泛型代替,这样一个泛型类就提取了出来,具体代码如下:
public class GenericSingleton<T> where T : Form, new()
{
private static T t = null;
public static T CreateInstrance()
{
if (null == t || t.IsDisposed)
{
t = new T();
}
return t;
}
}
GenericSingleton
泛型代码已经写好了,怎么在事件中调用呢,其实很简单和上面的用法基本相同,具体调用如下:
private void Add_Click(object sender, EventArgs e)
{
FrmAdd FrmAdd = GenericSingleton<FrmAdd>.CreateInstrance();
FrmAdd.Show();
}
button事件调用
运行程序,当我们单机按钮的时候,依然满足我们的要求,同时也为添加多个窗体使用单例模式的便捷性提供了可能。
本篇文章单例模式设计模式至此,谢谢您收看我的博客。
单例模式(Winform窗体的实现)的更多相关文章
- Winform 窗体单例
有窗体Form1和窗体Form2,单击Form1上按钮,只弹出一个Form2. Form2里自定义一个方法,里面判断是否弹出Form2,没有时弹出Form2. public static Form2 ...
- winform 窗体圆角设计
网上看到的很多winform窗体圆角设计代码都比较累赘,这里分享一个少量代码就可以实现的圆角.主要运用了System.Drawing.Drawing2D. 效果图 代码如下. private void ...
- WinForm 窗体属性 窗体美化
WinForm是·Net开发平台中对Windows Form的一种称谓. Windows窗体的一些重要特点如下: 功能强大:Windows窗体可用于设计窗体和可视控件,以创建丰富的基于Windows的 ...
- winform窗体置顶
winform窗体置顶 金刚 winform 置顶 今天做了一个winform小工具.需要设置置顶功能. 网上找了下,发现百度真的很垃圾... 还是必应靠谱些. 找到一个可以链接. https://s ...
- winform窗体控件(全)
回顾跟补充下除了昨天那常用6个其他的winform窗体控件作用 1:Button:按钮 (1)AutoSize:如果是True的情况下,内容将会撑开:False的话会另起一行 (2)Enabled: ...
- C#将exe运行程序嵌入到自己的winform窗体中
以下例子是将Word打开,然后将它嵌入到winform窗体中,效果如下图:C将exe运行程序嵌入到自己的winform窗体中 - kingmax_res - iSport注意:该方法只适用于com的e ...
- WinForm窗体嵌入
一.在winform窗体上添加两个控件 1.容器>Panel 2.添加 SideBar.dll (下载链接:http://pan.baidu.com/s/1o6qhf9w) (1)将SideBa ...
- C#实现WinForm窗体逐渐显示效果
C#实现WinForm窗体逐渐显示效果,这个博客园里面已经有其它人已经实现了,原理很简单,就是通过定时改变窗体的透明度(从0到1,即透明度从完全透明到不透明),我这里也是按照这个思路来实现的,但是我做 ...
- .NET vs2010中使用IrisSkin2.dll轻松实现winForm窗体换肤功能
IrisSkin2.dll是一款很不错的免费皮肤控件,利用它可以轻松的实现winForm窗体换肤! 网上很多朋友说在VS2010中不能使用IrisSkin2.dll,我这里提供一个取巧的办法. Iri ...
随机推荐
- Centos下使用gitosis配置管理git服务端(转载)
From:http://www.cnblogs.com/ahauzyy/archive/2013/04/08/3043384.html 说明:由于条件有限,我这里使用的是同一台centos的,但教程内 ...
- eclips中增加对jar包的引用
http://jingyan.baidu.com/article/ca41422fc76c4a1eae99ed9f.html
- 中文系统下,UTF-8编码文本文件读取导致的错误
一.UTF-8编码文件读取导致的错误 有个txt文件,里面内容为: aaa bbb ccc 以UTF-8编码方式打开txt文件,顺序读取,将里面的值放到一个hashset中,并判断aaa是否在在has ...
- golang.org/x/mobile/exp/gl/glutil/glimage.go 源码分析
看这篇之前,建议先看之前几篇,这几篇是基础. Go Mobile 例子 basic 源码分析 http://www.cnblogs.com/ghj1976/p/5183199.html OpenGL ...
- 算法库:基础线性代数子程序库(Basic Linear Algebra Subprograms,BLAS)介绍
调试DeepFlow光流算法,由于作者给出的算法是基于Linux系统的,所以要在Windows上运行,不得不做大量的修改工作.移植到Windows平台,除了一些头文件找不到外,还有一些函数也找不到.这 ...
- Python的方法分类
1.Python的类方法,实例方法,和静态方法 class S(object): def Test(self): print("TEST") @classmethod#类方法 de ...
- IIS报错,App_global.asax.×××.dll拒绝访问
解决方案: ①找到C:\Windows下的temp文件夹 ②属性->安全->编辑->添加IIS_IUSERS,给其添加上可读写的权限,然后应用,确定即可
- 《Code Complete》ch.21 协同构建
WHAT? 所有的协同构建技术都试图通过这样那样的途径,将展示工作的过程正式化,以便将错误暴露出来 WHY? 提高缺陷检出率,从而缩短开发周期,降低开发成本 发现不明显的错误信息,如不恰当的注释.硬编 ...
- HDU 1043 八数码 Eight A*算法
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 翻译:为 URL Rewrite 模块创建重写规则
原文名称:Creating Rewrite Rules for the URL Rewrite Module 原文地址:http://www.iis.net/learn/extensions/url- ...