CS Dev Guide: How to Write a Custom Chameleon Control
I have to change the name of my blog to "Custom Controls"! And this time I want to talk about writing a custom Chameleon control in a new CS Dev Guide.
But seriously how can you write a custom Chameleon control?! The first step is to understand the class hierarchy in Chameleon. Chameleon controls are located in some namespaces:
- There is a general CommunityServer.Controls namespace where you can find all Chameleon base classes and all controls that are used for general purposes.
- There are also some namespaces dedicated to controls that are used in a specific application. For example CommunityServer.Blogs.Controls contains all classes for blog controls.
Choose a Base Class
After understanding the complex class structure of Chameleon controls (I have a class diagram to share with you but it's almost impossible to get anything from this large and complex diagram) you need to choose a base class for your control based on the purpose of your control and its application. Chameleon has a large and complex class structure and I guess Ben can't remember all parts of this hierarchy himself but after working with Chameleon, you'll find that how many classes are important and common.
Some classes are the base class for many other classes. Some examples are WrappedContentBase, ConditionBase, ActionBase, WrappedFormBase, ... On the other side many other base classes are derived from these base classes as well so you have a complex structure ahead.
Here you need a good base class to choose and start your development based on it. This is an important step and needs some experiments with Chameleon.
Implement Your Logic
After passing previous step, you can create a class and derive it from your chosen base class and override some methods from base class or add your own methods and properties to customize it to add your desire functionality to it.
Some base classes like ActionBase have a Render() method. It takes an HtmlTextWriter as parameter and renders it as output. At one level you can customize the HTML code directly but most times you can customize some properties and methods from base classes to get what you want.
Let me write an example. I want to write a custom Chameleon control to customize default TagCloud control to show posts count for each tag and hide tags with less than 2 posts. To do this I use TagCloud as my base class and write a very simple code to set two properties of this base class in constructor.
using System;
using System.Collections.Generic;
using System.Text;
using CommunityServer.Components;
using CommunityServer.Controls;
namespace ChameleonControl
{
public class CustomControl : TagCloud
{
public CustomControl()
{
base.ShowTagCounts = true;
base.MinimumPostsPerTag = 2;
}
}
}
Register the Control
Now I compile my class library into an assembly and deploy it to bin folder. The last step is to use this control in my Community Server pages. To do this I have to register a tag prefix for my custom control and add it to my page like a custom server control. As you know ASP.NET well (or in other words I suppose that my readers have a good background in ASP.NET), it's possible to register a tag prefix from page directives or Web.Config. As the second option is a better way, I describe it.
In Community Server 2007 you can find following configurations in Web.Config file:
<pages validateRequest="false" enableEventValidation="false" autoEventWireup="true"
pageBaseType="CommunityServer.Components.CSPage, CommunityServer.Components">
<controls>
<add tagPrefix="CSControl" namespace="CommunityServer.Controls" assembly="CommunityServer.Controls" />
<add tagPrefix="CSBlog" namespace="CommunityServer.Blogs.Controls" assembly="CommunityServer.Blogs" />
<add tagPrefix="CSForum" namespace="CommunityServer.Discussions.Controls" assembly="CommunityServer.Discussions" />
<add tagPrefix="CSMail" namespace="CommunityServer.MailGateway.MailRoom.Controls" assembly="CommunityServer.MailGateway"/>
<add tagPrefix="CSFile" namespace="CommunityServer.Files.Controls" assembly="CommunityServer.Files" />
<add tagPrefix="CSGallery" namespace="CommunityServer.Galleries.Controls" assembly="CommunityServer.Galleries"/>
<add tagPrefix="CSReader" namespace="CommunityServer.Reader.Controls" assembly="CommunityServer.Reader"/>
<add tagPrefix="CSDynConfig" namespace="Telligent.DynamicConfiguration.Controls" assembly="Telligent.DynamicConfiguration"/>
<add tagPrefix="TWC" namespace="Telligent.Glow" assembly="Telligent.Glow" />
<add tagPrefix="CA" namespace="ComponentArt.Web.UI" assembly="ComponentArt.Web.UI"/>
<add tagPrefix="CP" namespace="CommunityServer.ControlPanel.Controls" assembly="CommunityServer.Web"/>
</controls>
</pages>
These are all default registered tag prefixes for Community Server controls. All you need is adding a new <add /> element with your own tag prefix, namespace and assembly name. After this you can simply add your custom control to all Community Server master and content pages as well as user controls and enjoy the intellisense! Here I add Keyvan as my prefix with my own namespace and assembly name.
<pages validateRequest="false" enableEventValidation="false" autoEventWireup="true"
pageBaseType="CommunityServer.Components.CSPage, CommunityServer.Components">
<controls>
<add tagPrefix="CSControl" namespace="CommunityServer.Controls" assembly="CommunityServer.Controls" />
<add tagPrefix="CSBlog" namespace="CommunityServer.Blogs.Controls" assembly="CommunityServer.Blogs" />
<add tagPrefix="CSForum" namespace="CommunityServer.Discussions.Controls" assembly="CommunityServer.Discussions" />
<add tagPrefix="CSMail" namespace="CommunityServer.MailGateway.MailRoom.Controls" assembly="CommunityServer.MailGateway"/>
<add tagPrefix="CSFile" namespace="CommunityServer.Files.Controls" assembly="CommunityServer.Files" />
<add tagPrefix="CSGallery" namespace="CommunityServer.Galleries.Controls" assembly="CommunityServer.Galleries"/>
<add tagPrefix="CSReader" namespace="CommunityServer.Reader.Controls" assembly="CommunityServer.Reader"/>
<add tagPrefix="CSDynConfig" namespace="Telligent.DynamicConfiguration.Controls" assembly="Telligent.DynamicConfiguration"/>
<add tagPrefix="TWC" namespace="Telligent.Glow" assembly="Telligent.Glow" />
<add tagPrefix="CA" namespace="ComponentArt.Web.UI" assembly="ComponentArt.Web.UI"/>
<add tagPrefix="CP" namespace="CommunityServer.ControlPanel.Controls" assembly="CommunityServer.Web"/>
<add tagPrefix="Keyvan" namespace="ChameleonControl" assembly="ChameleonControl"/>
</controls>
</pages>
At this point I add my control to a page.
<Keyvan:CustomControl ID="TagCloud2" TagCssClasses="tag6,tag5,tag4,tag3,tag2,tag1" runat="server"
IgnoreFilterTags="true" CssClass="TagCloud" TagCloudCssClass="TagCloud" />
And ...
Now playing: Bruce BecVar - Istanbul
[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.
10 Comments : 05.09.07
Feedbacks
It's great for newbie in programing Chameleon controls for CS. Wish you continue write several articles complex.
Thanks in advantage!
#1
The Wizard
05.09.2007 @ 5:40 PM