Generally, we can say that all web controls you are going to build for Sitefinity modules have several things in common. In this post I will explain how I’ve approached building a ControlPanel control for Contacts module. Once that is explained everything else should come pretty easy to you. At the end of this post you’ll find a link to the project so you can download it and examine (I’ve commented the project rather extensively).
There are two cornerstone ideas we have when we build any kind of control :
- Appearance of control is defined through a template. To control it should make no difference how the template is created
- Working with data is done through a manager class. It should make no difference to control how is data being stored, that’s up to provider.
Take a look at following diagram to get a high overview of how Web controls are built in Sitefinity.
Working with controls
On the left we have Web Control (blue) which represents ControlPanel in this example. This control acts as a wrapper control for the actual controls of ControlPanel. The child controls being (if you forgot how control panel should look like, take a look at this mockup Contacts module > View mode) :
- Add new contact - when clicked Control panel should switch from list mode to insert mode
- Contacts grid - Rad Grid that lists all the contacts
- Contact Editor - this control serves a purpose of adding new contacts or editing existing contacts (if you forgot, this is how this control looks like Contacts module > Insert / edit mode)
In order to allow designer / user experience expert to modify the look and feel of the controls without messing with the code and recompiling we load controls from template. This is where the GenericContainer kicks in. We are always going to instantiate the template inside a class that inherits from GenericContainer. Generic Container class allows us to define controls that are absolutely necessary for ControlPanel to be working (required controls), but also allows us to define the controls that can be there, but are not necessary (optional controls). So if a template creator forgets to add a Button control with the id of “addNewContact” an exception we’ll be thrown saying that template is missing a required “addNewContact” button. By using GenericContainer class we have an easy way to make a contract between a programmer and designer.
Template creator has two options when it comes to creating a template without coding. One is to create an user control and set it’s path in the web.config provider or he can declaratively create template. Note that it is only possible to create declarative template if the ControlPanel is added to the page or user control declaratively as well (it’s obvious that if we add ControlPanel dynamically we can’t create template declaratively).
Third option for creating a template is default template, class that inherits from ITemplate. You should always implement default template because it is possible that Page object will not be accessible at one time or another (Design) and you don’t want the control to crash at that moment.
If all this sounds messy, take a look at the diagram once again, download the project and examine the code, and then reread it again. This whole idea is actually much simpler than it sounds.
Working with data
In order to keep our control as flexible as possible, all the work with data will be done through manager (ContactsManager) in this example. Depending on how you initialize manager (without the provider name it will use ‘DefaultProvider’ or with the actual name of the provider) manager will decide which provider to use to work with data.
This, for example, allows you to move your data from Sql Server to XML without ever modifying the Web controls. All you need to do is create a new Data provider and initialize manager with the name of new provider.
Few last words
I’ve just explained the logic behind creating the controls. Understanding this logic should ease your decisions regarding where to create controls, how to bind controls to data and such. The detailed explanation you can get by examining the project, since I’ve commented all the crucial parts. Once again, if you have any questions, don’t hesitate to ask. Nothing would make me more happier that a request from you to write a blog post on a topic that has not be understood cleary
Since we’ve covered most of the topics so far, I won’t be explaining the project step-by-step anymore, but will point out important aspects. So from now on, I’ll be working more on the code and comments… while in posting I’ll let you know what has been added so you can see how to whole thing is rolling out.
YOU CAN DOWNLOAD THE PROJECT HERE
One more thing, once the module is completed I’ll make the entire solution (with Sitefinity Community Edition) available for download.