I'm Keyvan Nayyeri, a 25 years old Ph.D. student at
the Computer Science department of
the University of Texas at San Antonio.
I'm also
a Software Architect and Developer and previously held a B.Sc.
degree in Applied Mathematics.
This is my blog where I publish content about various topics specifically Programming Languages and Compilers, Software
Engineering and Programming.
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:
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.
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;
}
}
}
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
The Wizard
May 09, 2007 5:40 PM
#
Dave Burke
May 10, 2007 6:49 AM
#
Keyvan Nayyeri
May 10, 2007 9:04 AM
#
J-O Eriksson
May 10, 2007 2:43 PM
#
External Feeds
May 14, 2007 8:00 PM
#
Ben Tiedt's Blog
May 16, 2007 10:28 PM
#
Madhular Ayachit
Aug 23, 2007 4:19 AM
#
News
Oct 02, 2007 2:08 PM
#
Hemal
Oct 27, 2007 8:52 AM
#
slnavn2000
Aug 13, 2008 10:52 PM
#
It's great for newbie in programing Chameleon controls for CS. Wish you continue write several articles complex.
Thanks in advantage!
Leave a Comment