zoukankan      html  css  js  c++  java
  • 如何在不同窗体中传递数据

    窗体就是一个交互数据的地方,和用户进行交互,或同某些硬件进行交互等。有很多数据需经过多个窗体进行处理,所以数据在不同窗体中传递是我们程序人员经常遇到的,如何做怎样做对程序实现难易程度和稳定性起关键作用。

    从一个窗体往另一个窗体传数据,可以通过实例的公有方法和公有属性即可实现,这是很简单的,但从窗体实例把数据回传到调用窗体,很多人都做得不好。在我们现在的项目中有两种做法:

    1、在A 窗体创建B窗体的实例,在B窗体保存A窗体的引用,同时指A窗体的需要访问数据的控件设为公有,在B窗体直接获取和设置A 窗体的公有控件的数据。

    点评: UI控件在不同的窗体线程传递的时候,系统要保存该控件的状态,会花掉大量的资源,特别是在互相引用的时候,窗体的操作等动作会变得迟钝(这是从运行时观察到的)。可以说,窗体的所有控件我们都尽量保留其默认的private状态,不要做改变。

    所有的UI控件都是非线程安全的,UI组件如果在非创建的窗体线程中传递,是不能对控件的属性进行访问和改变的。时钟线程Forms.Timer是特别的,是可以直接访问创建其父线程所创建的UI控件(其他窗体的UI控件没有测试),System.TimerThread.Timer这两个时钟线程是不能直接访问线程外创建的组件(好像Framework1.0时是可以的)。以上传递数据的做法是以牺牲性能来换取逻辑实现。 

    2、通过一个全局变量存放要传递数据。两个窗体所要的数据都是从这全局变量中获取,分析其原因,可能是很多窗体都使用单例模式,从而把窗体的公开接口都给隐藏了。本人认为窗体类使用单例模式的做法欠妥,一个窗体作为程序的最顶层,往往有很多的属性和事件需要给调用方来控制的,单例模式使窗体失去灵活性,同时增加开发难度和增加代码量(除非功能的需求)。

    点评:全局变量存放要传递的数据,使代码难以阅读,增加维护的难度;同时,在一次交互只有一个实例的情况下是正确的,如果同一时间存在多个这样的实例进行操作,就不能保证数据的正确性了(或要对数据进行更多的控制),无论怎样加锁控制都是不可行,有时会产生逻辑上的错误。所以2的做法是不可取的。

    正确的做法(只说数据回传)

    1、从模式窗体中取得数据,这种情况在微软的应用程序使用最多的,我们是可以参考此做法。模式窗体类中设一个公有属性,在窗体关闭前从UI控件上取得要传递的数据,同时在OnFormClosing事件设定窗体的DialogResult属性。当模式窗体关闭后,其中的UI控件全部被销毁,但数据会被保留(机制不是很清楚),我们可以在ShowDialog()方法后通过判断窗体的DialogResult属性来确定是否需要回传(DialogResult.OK是要的,当用户通过标题栏的关闭按键来关闭或用户不需要回传可设为DialogResult.Cancel)。直接访问窗体实例的公有属性或公有方法即可取到回传的数据。

    2、从非模式窗体取得数据,这种情况是很少的。在微软的应用程序中,查询窗体就是典范。此种情况是两个窗体线程同时在跑,我们只能够通过消息机制来实现数据的回传。我们通过一个回传数据的事件,在事件参数中承载所需要的数据。

    以上观点有不正确的地方,请阅读者批正,共同学习,共同进步。
        新的设计思路:使用AOP(Aspect Oriented Programming面向方面编程)技术实现。完成后再同大家交流。

  • 相关阅读:
    sh_09_字典的定义
    sh_08_格式化字符串
    sh_07_元组遍历
    sh_06_元组基本使用
    sh_05_列表遍历
    sh_04_列表排序
    sh_03_列表的数据统计
    图片懒加载
    UA池和ip代理池
    爬虫篇 --- 分布式爬虫
  • 原文地址:https://www.cnblogs.com/Yjianyong/p/1547500.html
Copyright © 2011-2022 走看看