窗体的单例模式(MDI窗体只实例化一次)

制作时间:2009/9/22 21:00-23:00 第一次修订

1.目标:窗体的单例模式 和简单工厂(即:做一个通用的代码,让窗体只一次)
     在多文档窗体时特别有用, 其实,我在想,要是能让每个窗体都有这个方法,就好了,可惜改不了编译器

2.实现:
     1. 写个方法public Form ShowOnce(string formName) 参数为完整的窗体名(带命名空间),
        1.调用Application.OpenForms[name];打开窗体
    Form form=OpenForms[name]方法,判断窗体是否处于打开状态,如果没有打开则返回null 
           其中:参数name:纯粹的窗体名(字符串型,不带命名空间)
 2.用单例模式创建窗体,如果form为null,则创建;否则,form.Focus();
           其中用到反射(通过窗体名反射窗体),这样代码就具有了通用性
3.代码
     大致意思,按钮事件里直接调用方法,就可以打开窗体了;
              由于有返回类型,用户可以很方便设置form的各种属性
        //打开Form1的代码
        private void button1_Click(object sender, EventArgs e)
        {
            Form form = ShowOnce("FormSimpleInstance.Form1");
            form.StartPosition = FormStartPosition.Manual;//指定窗体的初始位置
            form.Location = new Point(400, 100);
        }
        //打开Form2的代码,其中,多加个一层命名空间
        private void button2_Click(object sender, EventArgs e)
        {
            Form form = ShowOnce("FormSimpleInstance.Cc.Form2");
            form.StartPosition = FormStartPosition.Manual;//指定窗体的初始位置
            form.Location = new Point(400, 100);
        }

        /// <summary>
        /// 打开窗体的通用方法,如果没有处于打开状态,则实例化并打开,否则将光标聚焦到窗体上
        /// </summary>
        /// <param name="formName">这个参数是完整的类名,命名空间+窗体名称</param>
        public Form ShowOnce(string formName)
        {
            Form form;
            string name=formName.Substring(formName.LastIndexOf(".")+1);//先得到窗体的名称(无命名空间)
            form = Application.OpenForms[name];//打开窗体,如果窗体是打开状态,则返回值不为null
            if (form != null)//如果窗体处于打开状态,则将光标聚集到窗体
            {
                form.Focus();
            }
            else//如果窗体不在打开状态,则通过简单工厂反射得到窗体,然后将窗体打开
            {
                Type type = Type.GetType(formName);
                if (type != null)
                {
                    form = (Form)System.Activator.CreateInstance(type);
                    form.Show();
                }
                else
                {
                    MessageBox.Show("检测OpenOnceForm方法的参数是否输入了完整的窗体类名",
                        "提示", MessageBoxButtons.OK);
                }
            }
            return form;

        }

4.放入代码片段:把这段代码放在vsIDE里是最好的啦,不过不知道怎么加进入,估计要用到组件...
               不过我把他做成了代码片段,放在Snippets里,感觉也不错
   1.制作code snippets:
       1.找到Snippets存放的目录,C:\Program Files\Microsoft Visual Studio 8\VC#\Snippets\2052\Visual C#
         直接复制到在文件夹的地址栏里,就可以找到,如果是安装在D盘,把C改成D就行
       2.新建文本文档->代码1复制进入(不要保存,点另存为,保存类型:所有类型,名称ShowOnce.snippets,确定)
   2.使用:
      随便新建一个项目,在类里面输入ShowOnce,然后按2次Tab键(就是键盘Q字母左边的那个),就成功了

  代码1:
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
 <CodeSnippet Format="1.0.0">
  <Header>
   <Title>ShowOnce</Title>
   <Shortcut>ShowOnce</Shortcut>
   <Description>类似Form的Show方法,不过是只打开一次</Description>
   <Author>肖新苗</Author>
   <SnippetTypes>
    <SnippetType>Expansion</SnippetType>
    <SnippetType>SurroundsWith</SnippetType>
   </SnippetTypes>
  </Header>
  <Snippet>
   <Declarations>
        <Literal></Literal>
   </Declarations>
   <Code Language="csharp"><![CDATA[
        /// <summary>
        /// 打开窗体的通用方法,如果没有处于打开状态,则实例化并打开,否则将光标聚焦到窗体上
        /// </summary>
        /// <param name="formName">这个参数是完整的类名,命名空间+窗体名称</param>
        public Form ShowOnce(string formName)
        {
            Form form;
            string name=formName.Substring(formName.LastIndexOf(".")+1);//先得到窗体的名称(无命名空间)
            form = Application.OpenForms[name];//打开窗体,如果窗体是打开状态,则返回值不为null
            if (form != null)//如果窗体处于打开状态,则将光标聚集到窗体
            {
                form.Focus();
            }
            else//如果窗体不在打开状态,则通过简单工厂反射得到窗体,然后将窗体打开
            {
                Type type = Type.GetType(formName);
                if (type != null)
                {
                    form = (Form)System.Activator.CreateInstance(type);
                    form.Show();
                }
                else
                {
                    MessageBox.Show("检测OpenOnceForm方法的参数是否输入了完整的窗体类名",
                        "提示", MessageBoxButtons.OK);
                }
            }
            return form;
        }
   ]]>
   </Code>
  </Snippet>
 </CodeSnippet>
</CodeSnippets>

你可能感兴趣的:(单例模式)