重构大型复杂的用户界面

Mar*_*ijn 9 c# user-interface winforms

我有一个很大的winform,上面有6个标签,里面装满了控件.第一个选项卡是主选项卡,其他5个选项卡是主选项卡的一部分.在数据库术语中,其他5个选项卡具有对主选项卡的引用.

你可以想象,我的形式变得非常庞大,难以维护.所以我的问题是,你如何处理大型UI?你怎么处理?

Nei*_*ell 11

在开始之前考虑你的目标.在我看来,你想要以SOLID原则为目标.除其他外,这意味着一个类/方法应该只有一个责任.在您的情况下,您的表单代码可能正在协调UI内容业务规则/域方法.

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

此外,研究UI设计模式.虽然很难在有状态的基于桌面的应用程序中实现,但MVC非常受欢迎且已经很成熟.这导致了MVP/被动视图MV-VM模式.就个人而言,我选择MVVM但是如果你不小心的话,你最终可以在WinForms中实现构建很多"框架代码" - 保持简单.

此外,开始考虑"任务"或"操作",因此构建基于任务的UI而不是具有相当于创建/读取/更新/删除(CRUD) UI的内容.将绑定到第一个选项卡的对象视为聚合根,并具有用户可以单击以执行特定任务的按钮/工具栏/链接标签.当他们这样做时,他们可能被导航到一个完全不同的页面,该页面仅聚合完成该工作所需的特定字段,因此消除了复杂性.

命令处理器

命令处理器模式基本上是用户发起事件的同步发布者/消费者模式.下面列出了一个基本(相当天真)的例子.

基本上,您尝试使用此模式实现的是从表单本身移动事件的实际处理.表单可能仍然处理UI问题,例如隐藏/ [dis/en] abling控件,动画等,但是真正的业务逻辑的关注点的清晰分离是您的目标.如果您有一个富域模型,"命令处理程序"将基本上协调对域模型上的方法的调用.命令处理器本身为您提供了一个在事务中包装处理程序方法的有用位置,或者也提供了审计和日志记录等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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)