c# - 重构大型复杂的用户界面

标签 c# winforms user-interface

我有一个很大的 winform,上面有 6 个选项卡,里面装满了控件。第一个选项卡是主选项卡,其他 5 个选项卡是主选项卡的一部分。在数据库方面,其他 5 个选项卡引用了主选项卡。

如您所想,我的表单变得非常庞大且难以维护。所以我的问题是,您如何处理大型 UI?你是怎么处理的?

最佳答案

开始前请考虑您的目标。你想瞄准 SOLID principles , 在我看来。这意味着,除其他事项外,类/方法应该具有单一责任。在您的情况下,您的表单代码可能正在协调 UI 内容业务规则/域方法。

分解为 usercontrols是一个很好的开始。例如,在您的情况下,每个选项卡可能只有一个用户控件。然后您可以保持实际的表单代码非常简单,加载和填充用户控件。您应该有一个命令处理器实现,这些用户控件可以发布/订阅,以启用 View 间对话。

此外,研究 UI 设计模式。 M-V-C非常流行和完善,但很难在有状态的基于桌面的应用程序中实现。这引起了M-V-P/passive viewM-V-VM模式。就我个人而言,我选择 MVVM,但如果不小心,在 WinForms 中实现时最终可能会构建大量“框架代码”——保持简单。

此外,开始考虑“任务”或“操作”,因此构建一个 task-based UI而不是拥有相当于 create/read/update/delete (CRUD) 的东西用户界面。将绑定(bind)到第一个选项卡的对象视为 aggregate root。 ,并具有用户可以单击以执行某些任务的按钮/工具栏/链接标签。当他们这样做时,他们可能会被导航到一个完全不同的页面,该页面仅聚合完成该工作所需的特定字段,因此消除了复杂性。

命令处理器

命令处理器模式基本上是同步的 publisher/consumer pattern对于用户发起的事件。下面包含一个基本的(相当幼稚的)示例。

从本质上讲,您尝试使用此模式实现的是将事件的实际处理 从表单本身移走。该表单可能仍会处理 UI 问题,例如隐藏/[dis/enable] 控件、动画等,但真正的业务逻辑的关注点完全分离是您的目标。如果你有 rich domain model ,“命令处理程序”实质上将协调对域模型上的方法的调用。命令处理器本身为您提供了一个有用的地方来将处理程序方法包装在事务中或提供 AOP -风格的东西,比如审计和日志记录。

public class UserForm : Form
{
    private ICommandProcessor _commandProcessor;

    public UserForm()
    {
        // Poor-man's IoC, try to avoid this by using an IoC container
        _commandProcessor = new CommandProcessor();
    }

    private void saveUserButton_Click(object sender, EventArgs e)
    {
        _commandProcessor.Process(new SaveUserCommand(GetUserFromFormFields()));
    }
}

public class CommandProcessor : ICommandProcessor
{
    public void Process(object command)
    {
        ICommandHandler[] handlers = FindHandlers(command);

        foreach (ICommandHandler handler in handlers)
        {
            handler.Handle(command);
        }
    }
}

关于c# - 重构大型复杂的用户界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6476736/

相关文章:

c# - 防止nhibernate中的Sql注入(inject)

c# - 如何使用 ValueMember 填充 ComboBox 编辑字段但在列表中显示 DisplayMember?

.net - .NET WinForms 中最大化 MDI 子项的多个控制按钮

user-interface - 有哪些很好的例子表明 "I am not the user"?

具有自定义渲染/绘图的 Python GUI

c# - 如何在 VS 2017 中创建具有最小依赖性的 .NET Standard NuGet 包?

c# - 依赖注入(inject)和程序集引用

c# - 如何在excel中创建一个可读的表格? C#

C# 使用自定义对象扩展包含列的 listView

c# - 为什么在按下鼠标按钮时我没有收到任何 MouseMove 事件?