开发者社区> soledad_lhc> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

单例模式——解决MDI子窗体实例化的问题

简介:                 机房收费系统进行有一段时间了,但是始终有些历史遗留问题。比如,如何MDI子窗体如何显示在上层的问题和MDI子窗体实例化的问题。         对于如何显示在上层的问题,这次采用的还是SetParent函数,在模块里面添加: '定义一个用来设置子...
+关注继续查看

      

         机房收费系统进行有一段时间了,但是始终有些历史遗留问题。比如,如何MDI子窗体如何显示在上层的问题和MDI子窗体实例化的问题。

        对于如何显示在上层的问题,这次采用的还是SetParent函数,在模块里面添加:


<span style="font-size:18px;"><span style="font-size:18px;"> '定义一个用来设置子窗体的函数
    Declare Function SetParent Lib "user32" Alias "SetParent" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long</span></span>


      接着,要解决的就是子窗体实例化的问题,然后查过一些方法之后,选择了单例模式。回过头去查自己当初学设计模式时的代码:

   

<span style="font-size:18px;"> <span style="font-size:18px;">public partial class FormToolbox : Form
    {
        private static FormToolbox ftb = null; //声明一个静态的类变量

        private  FormToolbox()  //将构造放改成私有的,外部代码不能直接new来实例化它
        {
            InitializeComponent();
        }

        private void FormToolbox_Load(object sender, EventArgs e)
        {

        }

        //得到类实例的方法,返回值就是本类对象,注意,此方法也是静态方法
        public static FormToolbox GetInstance()
        {
            
            if (ftb == null || ftb.IsDisposed)
            {
                ftb = new FormToolbox();
                ftb.MdiParent = Form1.ActiveForm;
            }
            return ftb;

        }

        
    }</span></span>

     

      大的方针制定好之后,开始动手写。。


     动手的时候,才会发现,学习的时候做的DEMON其实总是非常理想化的东西,实际中面临的问题往往更复杂。      


     复习了下设计模式之后,然后就开始写自己的VB.NET版本的了,为了解决窗体不美观的问题,这次还是加了容器空间,load的时候平铺窗体。


      但是,每次子窗体弹出来,总是会闪一下,然后消失,再点击按钮,让子窗体弹出来,这下才会变正常。就像《超级破坏王》中的云妮洛普一样,

       

      看起来就是程序中的BUG.  之后单步监视了很久,发现,调用setparent的时候,子窗体因为被前置,就会出现在主窗体的前面,但是在setparent之后,还是有了某某.Show()方法,这就造成了一个矛盾,setparent刚将窗体置前,show方法又将窗体隐藏在主窗体和控件的夹层里面了,╮(╯▽╰)╭  矛盾啊。改完这个之后,解决了闪现的问题。


     还有单例的问题:

 

<span style="font-size:18px;"><span style="font-size:18px;">If IsNothing(checkBalance) Or checkBalance.IsDisposed Then '如果没有实例化</span></span>

    但是,每次运行到这里的时候就会出错:“未将对象的引用设置到对象的实例的问题”

     

      细想下,刚刚声明的对象,根本没有new,在这行这句话的时候,IsNothing值为true,然后它会接着调用IsDisposed,这时就会出现问题,因为checkBalance根本就是Nothing嘛~这时想起了以前学习C#的时候学到的一个逻辑短路的问题:C语言的“逻辑短路”

    

    利用逻辑短路,可以很好的解决“未将对象的引用设置到对象的实例的问题”。

    so,只需查查VB.NET的逻辑运算符,然后我找到了OrElse。。。

   

     代码如下:

 

<span style="font-size:18px;">#Region "单例模式:用来判断本窗体是否已经实例化"

    Private Shared checkBalance As frmCheckBalance = Nothing  '定义一个静态的类变量

    Private Sub New()

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
    End Sub

    Public Shared Sub GetInstance() ' As frmCheckBalance '用来出现实例

        If IsNothing(checkBalance) OrElse checkBalance.IsDisposed Then '如果没有实例化
            '注意:1,要判断窗体是否已被实例化和窗体是否被销毁过(当关闭一个窗体时,资源被释放,但是并不是nothing)
            '     2,orelse产生了逻辑短路的问题,如果这里用Or会产生错误,因为可能会引用不存在的对象。

            checkBalance = New frmCheckBalance '实例化checkbanlance
        End If

        checkBalance.MdiParent = frmMain '设置父窗体
        checkBalance.Show()     '显示窗体出来,但是此时子窗体还是被隐藏在下层的,必须要通过SetParent将它拿到上层来
        SetParent(checkBalance.Handle.ToInt64, frmMain.Handle.ToInt64)  '设置窗体置前

        'Return checkBalance '返回
    End Sub

#End Region</span>

 

     上面对单例模式有所改动,但是不影响单例模式的灵魂。


     在主窗体里,只需调用sub 过程就好。


<span style="font-size:18px;"> Private Sub checkBalanceMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles checkBalanceMenu.Click

        frmCheckBalance.GetInstance()

    End Sub</span>

 

   PS:代码里面还是一点点BUG,正在修改中,希望路过的高手们指点一二~

   

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
WPF 绑定父类属性
原文:WPF 绑定父类属性 1.绑定父控件的属性. 1 2 3 4 5 6 7 8 9 发现问题,父控件的属性如果是后期加载的,别如说Width或者Height不是固定的数值,那么绑定时没有效果的。
917 0
c# 类操作 窗体 二
引用:http://blog.sina.com.cn/s/blog_5f4ffa170100ub8x.html 1、修改窗体控件的Modifiers属性Private为Public,使控件可以全程序访问;2、在类中实例化窗体static Form1 f = new Form1(); 3、在类中的函数中修改窗体控件(Label)的属性值f.labX42.Text = "通讯中断";4、注意:类中函数如果是static,则实例化窗体时也需要定义为static。
537 0
c# 类操作 窗体
引用:http://cgxcn.blog.163.com/blog/static/132312422009542570727/ 方法一: 我在做一个聊天程序的时候遇到这样一个问题,我需要将操作类与窗体分离,就是说类来实现所有的操作,窗体类中只进行调用类,如果是简单的操作,很容易实现,但是如果里面设计到有参数或有返回的线程,就可能有些困难,所以在这里说一下,用类来控制窗体部分控件的方法.
551 0
C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)
本文转载:http://www.csframework.com/archive/2/arc-2-20110805-1771.htm 文章侧重点主要是讨论“窗体”与“窗体”之间方法的调用,以及“MDI父窗体”与“Chilid子窗体”之间如何相互的调用方法。
669 0
[C#] winform 子窗体向父窗体传值
父窗框mainForm;子窗体childForm,利用事件进行传值在子窗体中的操作: public event EventHandler accept; public string value; private void btnStart_Click(object sender, EventArgs e) {   value=txtName.
621 0
WinForm中窗体间传值(中间类)
一个稍微复杂一点的程序一般都有两个或者更多的窗体。有时在程序设计中,数据不仅要在同一个窗体中传递,还要在窗体间传递,尤其是用子窗体如何改变父窗体。这个问题已经不少人问过,在群里也为了那种方式好而争论过,昨天雨声.net问窗体间互操作的问题,让我萌生就这个问题写下这篇文章,希望对刚刚接触C#的朋友有所帮助,有疏漏之处,也希望朋友们指正,欢迎讨论。
639 0
+关注
soledad_lhc
csdn博客:http://blog.csdn.net/lhc1105
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载