【问题标题】:Designing a windows application to maintain states across MDI child forms设计一个 Windows 应用程序来维护跨 MDI 子窗体的状态
【发布时间】:2015-07-16 03:26:20
【问题描述】:

这是一篇相当长的帖子,我将尽力解释我开发的应用程序的工作原理,并希望您能帮助将来扩展它。

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

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

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

正如“软件开发唯一不变的是变化”中的说法,出现了一个新要求,我需要为用户提供图形的暂停/停止功能选项。 我应该能够暂停图形(即暂停数据通信)并转到主窗口播放,还应该能够打开另一个窗口(CWindowSecond)再次播放图形(应该能够暂停这里也有交流)。回到第一个窗口CWindowFirst,继续之前保存的数据通信。

现在是百万美元的问题,我如何实现或修改现有设计以实现上述功能。

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

关于暂停命令我会

  1. 在暂停时停止通信(取消订阅通信事件)。
  2. 将事件数据缓冲区和图表的状态保存在集合中。
  3. 在退出前将完整对象序列化为文件。
  4. 返回相同的表单时,我将反序列化对象
  5. 从反序列化对象中获取事件数据缓冲区
  6. 填充图表并启用事件处理程序,以便我继续从通信层接收事件。

那里的专家我需要您的帮助。请指导/建议改进/分享您的想法

【问题讨论】:

  • 什么类型的通信?您是在监控多播还是 tcp?你是主(客户端)还是从(服务器)。需要答案才能提出正确的架构。是否必须向服务器发送命令才能停止发送?
  • 通过 TCP 通信。尽管坦率地说我的应用程序并不关心它是否通过 TCP/USB 串行。它基本上只是一个奴隶(接收者)。如果我订阅通信事件,我会收到数据,如果我取消订阅,我不会得到数据
  • 当取消暂停时,是不是:1)从它离开的地方继续,2)重置屏幕,3)立即渲染所有待处理的数据然后从那里继续?
  • 1.是的,在取消暂停时,它应该从它离开的地方重新启动----2.不,它不会重置屏幕----3.是的,它必须继续(即使这可能意味着这段时间之间的数据丢失)暂停和取消暂停的时间段)
  • 接收与显示分开。接收到的数据 - 将其存储在缓冲区中 - 复制缓冲区 - 从缓冲区的副本中显示 UI。然后你可以暂停并做任何你想做的事情

标签: c# design-patterns architecture ooad


【解决方案1】:

正如 HansPassant 所评论的,将数据(或上下文,或管理器,等等)从视图中分离出来。 Singleton 带有上下文构造函数注入是恕我直言的最佳选择。

使用非最干净的单例方式举例:

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
}

当然,这是不了解需求和当前架构的局外人建议的方法。应进行任何调整以满足要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多