Search code examples
c#winformscode-reuse

Leveraging pre-written view code in WinForms applications


My job involves writing relatively small WinForms applications in C#.NET. Sometimes I am given projects which are slight variants on projects that I have already completed. I've been able to leverage business logic code for re-use by abstracting the domain logic into its own assembly, and simply reference it in newer projects.

However, I've had to rewrite a lot of the view code (e.g. Forms). I've tried in the past to use inheritance with Form objects, but even though it worked it did not bode well with the designer, and also required some hacking to the project file in order to compile in the correct order. Is there an easy way to leverage my view code to be re-used in new projects?


Solution

  • I had troubles too to try to build true reusable pieces of UI code in my winforms projects.

    Then I managed to achieve this goal more or less by using UserControls, but it is cumbersome sometimes because it often requires a lot of properties / method to be subclassed when it is aimed to be reused in different projects with a very different layout.

    That's why I use Helper classes which set some controls properties, passing the control in parameter this way. For example:

    void SetupEditableGrid(UltraGrid myGrid)
    {
        myGrid.BackColor...
    }
    

    Also, for the most complex objects that requires more work, I am using controller classes associated with some specific controls. For example, I use a MyEditableUltraGridController to prepare a raw Infragistic's UltraGrid to be fully editable.

    public class MyEditableUltraGridController()
    {
        UltraGrid _myGrid;
    
        public MyEditableUltraGridController(UltraGrid myGrid)
        {
            _myGrid = myGrid;
            _myGrid.InitializeLayout += ... // some common initialization code
            _myGrid.KeyPressed += ... // some keystroke handling code
            ... etc ...
        }
    
        void InitializeLayout(object sender, EventArgs e)
        {
            ... some specific UltraGrid common initialization code
        }
    
        ... // some code that make my UltraGrid editable, etc...
    }
    

    Then, considering an existing UltraGrid1 control on my form, I will have :

    Form_Load(object sender, EventArgs e)
    {
        var MyEditableUltraGridController = 
            new MyEditableUltraGridController(UltraGrid1);
    }
    

    I feel confortable with this class based approach, because it allows me to maintain control behaviour a confortable way with a good flexibility.