RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1598780
Accepted
James Bond
James Bond
Asked:2024-11-04 17:55:21 +0000 UTC2024-11-04 17:55:21 +0000 UTC 2024-11-04 17:55:21 +0000 UTC

哪种程序架构最适合 MDI 界面?

  • 772

多文档界面意味着程序将至少有两种表单 - 主表单(容器)和表单,其副本将在主表单内创建。

最初,我计划将我的程序建立在经典 MVC 的基础上,但如果一个控制器同时负责主窗体和子窗体,在我看来,这似乎是一个重大违规,会使控制器变得过于复杂。

但具有 MDI 界面的程序非常常见,并且可能已经有一个经过验证且非常适合它们的架构。请告诉我,具体是哪一个?

PS 目前我认为下面的配置是最成功的: 在此输入图像描述

c#
  • 2 2 个回答
  • 59 Views

2 个回答

  • Voted
  1. Pavel Mayorov
    2024-11-05T20:44:01Z2024-11-05T20:44:01Z

    有许多经过验证且合适的架构(MVC、MVP、MVVM),它们都有一个共同的缺点 - 它们太抽象,不能回答代码实际应该如何编写的问题。

    事实上,MVC 是如此抽象,以至于在 Habré 上人们仍然定期争论表单到底是什么 - 模型、控制器或视图

    因此,我建议降低一点。所以,你有两种形式,你需要以某种方式连接它们。而且,正如您自己所注意到的,建议确保子表单不了解父表单。

    有三种方法可以做到这一点。

    方法1.通过通用模型。

    子窗体可以更改模型中的属性(最好通过数据绑定),模型将发送事件,主窗体将做出反应(最好通过数据绑定)。这也适用于相反的方向。

    当然,这并不意味着主窗体和子窗体的模型必须在字面上是通用的。请记住,与其他 MVC 组件一样,模型可以分为独立的子模型或分层相关的子模型。将模型所需的部分传递给子窗体。

    方法2.通过事件

    子窗体可以声明事件,主窗体可以订阅该事件。

    方法三、通过接口

    当事件不够或太多时。

    子窗体可以在构造函数中请求某些接口(例如,IChildFormOwner或IChildFormHost),主窗体可以实现它(直接或通过内部类)。

    方法4.通过任务

    通常,一种罕见的方法仅适用于一种情况 - 在对话框表单中,其任务是向用户请求数据。在这种情况下,表单的生命周期可以很好地封装成异步方法,例如 ShowAsync:

        private readonly TaskCompletionSource tcs = new();
    
        private void bthOk_Click(object sender, EventArgs e)
        {
            tcs.TrySetResult();
            Close();
        }
    
        private void btnCancel_Click(object sender, EventArgs e)
        {
            tcs.TrySetCanceled();
            Close();
        }
    
        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            tcs.TrySetCanceled();
            base.OnFormClosed(e);
        }
    
        public Task ShowAsync()
        {
            Show();
            Activate();
            return tcs.Task;
        }
    
    • 2
  2. Best Answer
    Faraday
    2024-11-04T20:53:29Z2024-11-04T20:53:29Z

    对于MDI项目,您可以使用以下常见架构模式之一:

    • 多维控制器
    • MVP
    • MVVM
    • 文档视图

    您可以根据您对上述各项的理解来使用上述任何一项。让我们考虑一下该模式的组织MVC。一般来说,值得注意的是,使用 会更正确MVVM,它按规则运行MVC,但用于桌面应用程序并具有一些功能。

    如果我们超越经典应用程序MVC,控制器必须负责某个狭窄的区域,并提供处理与该区域相关的数据的所有必要方法。

    根据相关评论中的要求,我可以假设为每个表单使用单独的控制器并不是一个坏主意。管理子表单可以通过将适当的参数传递给控制器​​来完成,您还可以存储子表单的链接并从父表单调用一些方法

    在此输入图像描述

    与父控制器的交互可以通过callback一个函数来实现,该函数可以在初始化期间传递给构造,或者在调用时传递给子控制器的方法。执行逻辑大致如下图所示(抱歉我的画功)

    在此输入图像描述

    这样,您就不会使用不属于主控制器的操作使主控制器过载,而是能够将它们移动到子控制器级别,并且如果需要,您还可以维护控制器之间的依赖关系。

    为了保持控制器之间的依赖性和通信,我仍然会选择stateless这种方法。要点是所有交互都是通过数据库或有状态服务进行的。但值得注意的是,如果您希望在程序中动态更改而不保存状态,则这种方法不太适合。该方法的结构如下图所示。

    在此输入图像描述

    • 1

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5