Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 设计windows应用程序以跨MDI子窗体维护状态_C#_Design Patterns_Architecture_Ooad - Fatal编程技术网

C# 设计windows应用程序以跨MDI子窗体维护状态

C# 设计windows应用程序以跨MDI子窗体维护状态,c#,design-patterns,architecture,ooad,C#,Design Patterns,Architecture,Ooad,这是一篇相当长的文章,我将尽我最大的努力解释我开发的应用程序的工作原理,并希望您帮助我在将来扩展它 我需要用C#设计一个基于windows的应用程序,它基本上监视来自外部通信源的事件,并将数据绘制在图形上。应用程序订阅来自通信对象的事件,并在出现数据事件时更新UI。这些监控类中的图形组件将使用通信数据缓冲区中的数据将数据绘制为线形图 为了实现这一点,我创建了一个工厂类,它将根据我提供的模型信息(设备模型类型)实例化一个特定的监控类(CWindowFirst或CWindowSecond等) 这些

这是一篇相当长的文章,我将尽我最大的努力解释我开发的应用程序的工作原理,并希望您帮助我在将来扩展它

我需要用C#设计一个基于windows的应用程序,它基本上监视来自外部通信源的事件,并将数据绘制在图形上。应用程序订阅来自通信对象的事件,并在出现数据事件时更新UI。这些监控类中的图形组件将使用通信数据缓冲区中的数据将数据绘制为线形图

为了实现这一点,我创建了一个工厂类,它将根据我提供的模型信息(设备模型类型)实例化一个特定的监控类(CWindowFirst或CWindowSecond等)

这些类实现用于初始化、数据采集和清理操作的标准契约(IFactoryInterface)。因此,在任何给定的时间点,我都可以实例化一个特定的类,并启动监视操作,以接收数据并在流程中填充图形。到目前为止还不错,我可以以图形的形式显示特定设备的数据。同时,每当主应用程序选择另一个窗口(即CWindowSecond或CWindowThird)时,我正在销毁(处理)CWindowFirst的对象

正如“软件开发中唯一不变的是变化”中所说的那样,出现了一个新的需求,我需要给用户一个选项来暂停/停止图形的功能。 我应该能够暂停图形(即暂停数据通信)并转到主窗口播放,还应该能够打开另一个窗口(CWindowSecond)再次播放图形(也应该能够在此处暂停通信)。返回第一个窗口CWindowFirst并恢复先前保存的数据通信

现在是一个百万美元的问题,我如何实现或者更确切地说是修改现有的设计来实现上述功能

我可以想到下面的实现,但我不确定它是否真的是一个实用的实现

在发出暂停命令时,我将

  • 暂停时停止通信(取消订阅通信事件)
  • 将事件数据缓冲区和图形的状态保存到集合中
  • 在退出之前将完整对象序列化为文件
  • 返回到相同的形式后,我将反序列化该对象
  • 从反序列化对象获取事件数据缓冲区
  • 在图中填充并启用事件处理程序,以便我继续从通信层接收事件

  • 专家们,我需要你们的帮助。请引导/建议改进/分享您的想法

    正如HansPassant评论的那样,将数据(或上下文,或经理,无论什么)从视图中分离出来。使用上下文构造函数注入是IMHO的最佳选择

    使用最不干净的单例方式的示例:

    public class MonitoringContext {
        public static MonitoringContext CurrentContext = new MonitoringContext();
    
        // handle generating data
        // handle populating data needed for graph
        // handle other action from other forms as well
    }
    
    public class FormGraph : Form{
        // default constructor if you do not have access to MDI
        public FormGraph(){
            this.context = MonitoringContext.CurrentContext;
        }
        public FormGraph(MonitoringContext context){
            this.context = context;
        }
        MonitoringContext context;
    
        // do whatever you want with context
    }
    
    public class FormOther : Form{
        // default constructor if you do not have access to MDI
        public FormOther(){
            this.context = MonitoringContext.CurrentContext;
        }
        public FormOther(MonitoringContext context){
            this.context = context;
        }
        MonitoringContext context;
    
        // do whatever you want with context
        // any changes reflected at the FormGraph
        // because of same reference and mutability
    }
    

    当然,这是来自不了解需求和当前体系结构的外部人员的建议方法。应进行任何调整以满足要求。

    什么类型的通信?您正在监视多播还是tcp?您是主(客户端)还是从(服务器)。需要回答才能提出正确的体系结构。您是否必须向服务器发送命令以停止发送?通信是通过TCP进行的。虽然我的应用程序并不关心它是否通过TCP/USB串行。它基本上只是一个从机(接收器)。如果我订阅通信事件,我会收到数据如果我取消订阅,我不会在取消订阅时获得数据,是不是:1)从它离开的地方继续,2)重置屏幕,3)立即呈现所有挂起的数据,然后从那里继续?1。是,取消暂停时,应从离开的位置重新启动------2.否,不应重置屏幕------3.是,必须继续(即使可能意味着暂停和取消暂停之间的数据丢失)单独接收和显示。接收数据-将其存储在缓冲区中-复制缓冲区-显示缓冲区副本的UI。然后你可以停下来,想做什么就做什么