Designing extensible modules - best practices: Child control ambivalence

Designing extensible modules - best practices: Child control ambivalence

April 17, 2009 0 Comments

The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.

[This post is part of the developer's manual preview published on this blog. You can find temporary TOC here.]

We know that every View has associated user interface with it, being defined in the underlying template. In order to make the View perform certain functionality, View will need to obtain reference to the controls from the template. For example, if View will bind data to a RadGrid control in the template (which has the ID of “dataGrid”), we can get the reference to this control in following manner:
RadGrid dataGrid = base.Container.GetControl<RadGrid>("dataGrid"true); 
The base here is a ViewModeControl or ViewModeUserControl which has already instantiated the specified template inside of its Container property. The Container property on the base class is of GenericContainer type and has a very helpful GetControl method, which you can use to get the reference to the control inside of a template.


While, the approach we have demonstrated will work fine there are several problems we may run into:

  • We have obtained the control in a private field. If we happen to need the reference to the RadGrid control, we’ll need to repeat this code throughout our View
  • Being the private field, Views that derive from our View will not be able to access it and will need to repeat the logic for obtaining the reference to the control
  • We have “hard-coded” the ID of the control to “dataGrid”. If we are to derive from this View and would implement a new template for the View, we would not be able to change the id of the grid in the template, but would be stuck with the “dataGrid”.
  • We have made the dataGrid control required (by passing the “true” as a second argument). In our derived View, we may decide that we don’t need this grid. But since the control is required, removing the grid from the template would throw an exception.

So, we have seen that there are many problems associated with this approach. The better and more flexible approach would be to declare a virtual property which would hold the reference to a particular control. The code would look like this:

protected virtual RadGrid DataGrid 
            return base.Container.GetControl<RadGrid>("dataGrid"true); 
Let us see how this approach solves the problems that come with private declarations.


First of all, we don’t need to call the GetControl method every time we need to reference the grid. Instead, we can now simply call the property. So, let us suppose we’d like to enable the sorting on the grid in any given method; all we need to do is this:

this.DataGrid.AllowSorting = true
Along these lines goes the second problem, with the access from derived classes. Since we have declared our property as protected, it means that we will be able to access the same property from the derived View. Let us suppose that we wish to disallow sorting in the derived View; all we need to do is this:
base.DataGrid.AllowSorting = false
The third problem we have mentioned was the hard coding of the id to “dataGrid”. Let us suppose we are making a more specialized View, by deriving from base View and we’d like to have the id of the grid to be “financialGrid” instead of “dataGrid”. Marking our property as virtual in the base View will allow us to override the property in the derived View as follows:
protected override RadGrid DataGrid 
               return base.Container.GetControl<RadGrid>("financialGrid"true); 
Since all of our code is working with the DataGrid property, we were able to safely change the id of the referenced control in one single place.


Finally, we had the problem of having our DataGrid being a required control. Similarly to the problem of hard-coded id, we can again override the property and make the control optional.

protected override RadGrid DataGrid 
                return base.Container.GetControl<RadGrid>("financialGrid"false); 
It is important to note that if you are working with optional controls, you should always check that the object is not null before using it. For example:

if(this.DataGrid != null
       this.DataGrid.AllowSorting = true


The Progress Team

View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments are disabled in preview mode.
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

More From Progress
ProgressNEXT: Premier Event for Modern Application Development
Read More
Seven Reasons to Check Out Sitefinity 11.1
Read More
Getting Started with Your Omnichannel Content Strategy
Read More