Search code examples
c#winformsevent-handlingorganization

Managing EventHandlers within a large Form


I'm developing a WinForm application and I've done a pretty bad job thus far of managing the size and contents. I was hoping someone could give me an example of how to break out some of the logic that I have within the main form cs file.

Here is an example of an EventHandler function that I have within my MainWindow.cs:

    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;
                }
            }
        }
    }

So this is simply one of many EventHandler's that I have within a Form. I created a MainForm which has a Tabbed Pane and has a collection of Tabs which have buttons, textboxes, checkboxes etc in each tab. All of the events that I handle go into the MainForm.cs file and now I've got close to 1,000 lines in this one file.

Can someone give me a simple example (or a article/document) detailing good structure? Can I define my EventHandler functions in a separate class (if so, how would this work...) Do I create some sort of static Helper class where I simply pass the instance of the objects i need to manipulate? I.E.

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

Where 'this' is the Form itself which has all the references to the objects I need to manipulate?

It's probably worth noting that I've learned a good bit about the Cross-Thread calls and I've started making Extension methods for many instances that I need which are simplistic.

Another question - I notice that the Visual Designer automatically makes all Components created with it private by default, is it in general a bad idea to make these internal and use the form object to reference these components as needed from outside the class? If it is not a good idea, what is better?


Solution

  • First I would suggest to separate independent user-interface parts into UserControls or Components. Then - if needed - wire them using Events (eg. your own specialized events and properties.

    For example you can place your main content (the TabControl / Container) in a UserControl and place that user control in the main form. All tab-/page-switching logic/UI etc. then belongs to that user control. In that UserControl you can define for example your own Event that gets fired when the user switches a tab. The main form then can register to this event - just like it can for other Winforms-control-events - and do its stuff (eg. change the window title to represent the currently active tab).

    Then next you can move the content of each tab to its own user-control and use these user-controls within your new tabs-usercontrol. Move the logic down to the UserControl which is responsible for the given task.

    A form/controls hierarchy from some typical application could look like this:

    • MainForm (Form)
      • MainTabContainerControl (UserControl)
      • Page1Control (UserControl)
      • Page2Control (UserControl)
        • MyImprovedDbRowGridControl (UserControl or Component)
      • Page3Control (UserControl)
      • SidebarControl (UserControl)
      • SearchControl (UserControl)
        • MyImprovedDbRowGridControl (UserControl or Component)
      • QuickHelpControl (UserControl)

    Next thing is so keep all the UI-eventhandlers as small as possible and doing only UI stuff. Move other logic like business- or dataaccess-logic to other classes outside of the user-interface.

    If you have combinations of the controls that are needed more then once in the application: move them to a re-usable UserControl. (eg. breadcrum).

    Regarding your sample code you can make it more compact and therefore maintainable by simplyfing its logic:

    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;
    }
    

    ...could be:

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

    Update: When it comes to refactoring and code-cleanup a very usefull tool is Resharper (R#). I can highly recommend it.

    Hope this gives you some ideas where to start.