【问题标题】:How do I handle events from controls inside a User Control derived from a Tab Page meant to be added dynamically to a Tab Control at run time?如何处理从标签页派生的用户控件内的控件的事件,该标签页旨在在运行时动态添加到标签控件?
【发布时间】:2011-03-28 11:28:59
【问题描述】:

我创建了一个派生自选项卡页的用户控件,其中包含某些控件,例如 ListView、按钮和文本框,以便在运行时动态地将选项卡页添加到选项卡控件。

如何在我的标签控件所在的主窗体中处理来自每个用户页面(这些用户控件标签的多个实例)中的此类控件的事件?最初,我希望能够将每个用户页面内的某些控件中的数据传回主窗体。

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    这不仅仅与标签页有关,尽管我们使用以类似方式派生的标签页。通过 UI 随意发送事件让我很困惑(保持各种事件触发的顺序等等)。相反,我创建了一个控制器类,它传递给各种 UI 组件,这些组件通知控制器发生变化,并且 UI 元素订阅控制器上的事件以接收有关环境的信息。

    为了具体化,每个派生的标签页都传递了一个对控制器的引用。他们可能会根据用户操作更改控制器的状态。假设当前记录已更改,UI 调用控制器上的一个方法告诉它新记录。

    页面上的其他 UI 元素会收到此更改的通知,因为它们订阅了控制器的 OnCurrentRecordChange 事件。

    虽然这引入了另一个类,但优点是您有一个控制器来协调对 UI 的更改,而不是一堆事件渗透和传递信息。我发现这也打破了对 UI 元素协作的依赖关系:我可以添加、删除或更改 UI 元素,只要它们都与控制器对话以进行更新,那么代码返工就会少得多。

    如果您曾经发现自己在调试 UI“循环”(其中一个控件的更改会触发其他控件的更改,这些更改会触发更多最终影响原始组件的更改),那么控制器类的额外工作将立即得到回报.

    更新:回答您的评论...第一站是阅读模型视图控制器架构:http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller

    举个具体的例子:http://www.dotnetheaven.com/Uploadfile/rmcochran/MVC_intro02012006001723AM/MVC_intro.aspx

    在使用 Windows 窗体时,许多人会陷入两层设计:UI + 数据层。绑定系统使这变得非常自然,因为有一种获取数据的简单方法(实体框架、LINQ)和一种将数据连接到 UI 的简单方法(设计人员)。在它们之间添加一个控制器并不像看起来那么难。

    在我的工作中,我使用 LLBLGen (http://www.llblgen.com/defaultgeneric.aspx) 作为我的低级数据层,但您可以替换 LINQ 或实体框架或任何其他数据访问工具,并且总体概述是相同的。

    在这一层之上,我构建了我的业务对象。它们中的许多只不过是 LLBLGen 对象的外观(如果我的业务规则对实体没有说太多的话),而另一些则内置了很多验证,它们将几个低级对象聚合成更可用的业务对象。最后还有一些业务对象,它们背后没有直接的实体(例如,系统之间的通信对象)。

    我提到的控制器对象与我的业务对象并存,因为它知道这些对象,甚至将它们交给 UI 以进行数据绑定。当 UI 想要进行更改时,它会通知控制器并使用业务对象来确保允许更新,如果允许,则将更改传递回数据层。

    在维基百科的图表中,视图是我的 UI。 Controller 是我的协调对象,它在两个方向上调解变化,而 Model 是我的业务对象层(在此之下具有较低级别,但这是对较高层隐藏的实现细节)。

    虽然从“视图 模型”(经典数据绑定)到“视图 控制器 模型”似乎增加了复杂性,但主要的好处是控制器成为了关于应用程序的“真相”。 UI 从控制器请求数据,因此控制器知道所有具有给定数据绑定的 UI 元素。如果事情发生变化,一个事件会通知所有 UI 元素,并且它们会在用户视觉上发生变化。好消息是关于系统状态有一个“真相”,这就是控制器正在为 UI 管理的真相。

    当需要持久化数据时,请求会转到控制器以更新模型。同样,我们有一个地方来协调保存和后续更新。所有数据验证完整性规则都在业务逻辑层(模型)中,因此控制器的代码保持简洁。

    通过分离 UI 关注点、协调关注点和业务逻辑关注点 你最终每个都有非常“轻量级”的方法和属性。更重要的是,每个子系统都可以对应用程序采取非常简单的视图,因为它们专注于拼图的那一部分,而不是在一个单一的代码中处理事件、UI 更新和数据更新。

    为了进一步阅读,我会推荐任何有关 ASP.NET MVC 的文章或书籍。虽然这不是 Winforms,但 MVC 基础的基本ideas 可以应用于 winforms。这里也有一些不错的 cmets:https://stackoverflow.com/questions/2406/looking-for-a-mvc-sample-for-winforms

    我应该清楚,我对我的项目所做的可能不被认为是“纯粹的”MVC,而只是沿着我们开发的应用程序中发现的自然断层线分离关注点。我们不为此使用“框架”(尽管涉及一些代码生成)。

    【讨论】:

    • 您能详细说明一下这个控制器类吗?是否有任何基于这种方法的开源项目或示例我可以研究以完全掌握这个概念?
    猜你喜欢
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 2016-05-15
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多