在大型表单中管理EventHandler

时间:2012-09-05 01:19:56

标签: c# winforms event-handling organization

我正在开发一个WinForm应用程序,到目前为止,我在管理大小和内容方面做得非常糟糕。我希望有人能给我一个例子,告诉我如何在主要的cs文件中打破一些逻辑。

以下是我在MainWindow.cs中的EventHandler函数示例:

    private void GroupBoxRequestTypeCheckedChanged(object pSender, EventArgs pEventArgs)
    {
        RadioButton vRadioButton = pSender as RadioButton;

        if (vRadioButton != null)
        {
            this.fSelectedButton = vRadioButton.Checked ? vRadioButton : null;

            if (vRadioButton.Equals(this.RadioButton_Copy) || vRadioButton.Equals(this.RadioButton_Delete) || vRadioButton.Equals(this.RadioButton_Download)
                || vRadioButton.Equals(this.RadioButton_Move) || vRadioButton.Equals(this.RadioButton_Upload))
            {
                this.GroupBox_Files.Enabled = true;
                this.GroupBox_Variables.Enabled = false;
            }
            else
            {
                this.GroupBox_Files.Enabled = false;
                this.GroupBox_Variables.Enabled = true;
            }
            if (this.fSelectedButton != null)
            {
                if (this.fSelectedButton.Equals(this.RadioButton_Delete))
                {
                    this.TextBox_DestinationFile.Enabled = false;
                    this.Button_DestinationBrowse.Enabled = false;
                }
                else
                {
                    this.TextBox_DestinationFile.Enabled = true;
                    this.Button_DestinationBrowse.Enabled = true;
                }
            }
        }
    }

所以这只是我在Form中的许多EventHandler中的一个。我创建了一个MainForm,它有一个Tabbed窗格,并有一个Tabs集合,每个标签中都有按钮,文本框,复选框等。我处理的所有事件都进入MainForm.cs文件,现在我在这个文件中有近1000行。

有人能给我一个简单的例子(或文章/文件)详细说明好的结构吗?我可以在一个单独的类中定义我的EventHandler函数(如果是这样,它将如何工作......)我是否创建了某种静态Helper类,我只需传递我需要操作的对象的实例?即。

    private void GroupBoxRequestTypeCheckedChange(object pSender, EventArgs pEventArgs)
    {
        HelperClass.HandleGroupBoxRequestTypeCheckedChanged(pSender, pEventArgs, this);
    }

哪个'this'是Form本身,它包含了我需要操作的对象的所有引用?

值得注意的是,我已经学习了很多关于跨线程调用的知识,并且我已经开始为我需要的许多实例制作扩展方法,这些方法很简单。

另一个问题 - 我注意到Visual Designer会默认自动创建所有使用它创建的组件,这通常是一个坏主意,使这些内部并使用表单对象从类外部根据需要引用这些组件?如果这不是一个好主意,那还有什么更好的呢?

1 个答案:

答案 0 :(得分:1)

首先,我建议将独立的用户界面部分分成UserControls或Components。然后 - 如果需要 - 使用事件(例如您自己的专门事件和属性)连接它们。

例如,您可以将主要内容(TabControl / Container)放在UserControl中,并将该用户控件放在主窗体中。然后,所有标签/页面切换逻辑/ UI等属于该用户控件。在该UserControl中,您可以定义自己的事件,当用户切换选项卡时会触发该事件。然后,主窗体可以注册到此事件 - 就像它可以用于其他Winforms-control-events一样 - 并执行其中的操作(例如,更改窗口标题以表示当前活动的选项卡)。

接下来,您可以将每个选项卡的内容移动到其自己的用户控件,并在新的tabs-usercontrol中使用这些用户控件。将逻辑向下移动到负责给定任务的UserControl。

某些典型应用程序的表单/控件层次结构可能如下所示:

  • MainForm(表格)
    • MainTabContainerControl(UserControl)
    • Page1Control(UserControl)
    • Page2Control(UserControl)
      • MyImprovedDbRowGridControl(UserControl或Component)
    • Page3Control(UserControl)
    • SidebarControl(UserControl)
    • SearchControl(UserControl)
      • MyImprovedDbRowGridControl(UserControl或Component)
    • QuickHelpControl(UserControl)

接下来就是保持所有的UI事件处理程序尽可能小,只做UI的东西。将业务或数据访问逻辑等其他逻辑移至用户界面之外的其他类。

如果您在应用程序中有多次需要的控件组合:将它们移动到可重复使用的UserControl。 (例如,breadcrum)。

关于您的示例代码,您可以通过简化逻辑来使其更紧凑,更易于维护:

if (this.fSelectedButton.Equals(this.RadioButton_Delete))
{
    this.TextBox_DestinationFile.Enabled = false;
    this.Button_DestinationBrowse.Enabled = false;
}
else
{
    this.TextBox_DestinationFile.Enabled = true;
    this.Button_DestinationBrowse.Enabled = true;
}

......可能是:

    var delete = fSelectedButton == RadioButton_Delete;
    this.TextBox_DestinationFile.Enabled = !delete;
    this.Button_DestinationBrowse.Enabled = !delete;

<强>更新 在重构和代码清理方面,一个非常有用的工具是Resharper(R#)。我强烈推荐它。

希望这能为您提供一些从哪里开始的建议。