CONTENTSTART
EXCLUDESTART EXCLUDEEND

Extending Kentico's ControlExtender

Many of you have probably used the ControlExtender class to extend Kentico’s various User Interfaces, such as the Edit Binding template, or Object Listing.  Or maybe you've even used it to extend an inherited Form Control.  But how many realize that this ControlExtender can really extend any control?

How the ControlExtender Works

The ControlExtender is pretty nifty.  How it works is when you identify a ControlExtender for a control (of the control type), it takes that control and recursively searches all the child controls until it finds one of the matching control type the extender is for.

Then, it executes on the OnInit (more specifically, the base.OnInit() of the control), passing the found Control to your extender.  The ControlExtender then provides the property Control to be used on it's OnInit which is the control it found.

Leveraging This

Knowing this, you can really use the ControlExtender to extend your own controls, including web parts.   To show an example, I created a very simple webpart with a Textbox.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyTextbox.ascx.cs" Inherits="CMSWebParts_Custom_MyTextbox" %>
<asp:Panel runat="server" ID="pnlContainer">
    <asp:TextBox runat="server" ID="tbxItem" />
</asp:Panel>

using CMS.Helpers;
using CMS.PortalEngine.Web.UI;
using System;
public partial class CMSWebParts_Custom_MyTextbox : CMSAbstractWebPart
{
    public string Text
    {
        get
        {
            return ValidationHelper.GetString(GetValue("Text"), "");
        } set
        {
            SetValue("Text", value);
        }
    }
    protected override void OnInit(EventArgs e)
    {
        string ThisHitBeforeExtender = "";
        base.OnInit(e); // The Extender was triggered here.
        string ThisHitAfterExtender = "";
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        tbxItem.Text = Text;
    }
}

And then created an extender

using CMS;
using CMS.Base.Web.UI;
using System.Web.UI.WebControls;
[assembly: RegisterCustomClass("TextboxExtender", typeof(TextboxExtender))]
public class TextboxExtender : ControlExtender<TextBox>
{
    public override void OnInit()
    {
        Control.CssClass = "my-class";
    }
}

Now so far so good, we have the control, we have an extender…but how do we apply it?  Well within the Web part dialogue, by default it doesn’t show the Code Behind Extender properties.  But, if you set the WebPart’s “Type” to UI on the General tab of the WebPart, then that property is unlocked.

Set the Webpart Type to UI

Now, you can see the Code Behind option and can set your extender:

Set the Extender Assembly and Class

After bringing up the control, and viewing the source, we now see that the CSS Class was set by the Extender:

Applications

There are many possible applications, but the bigger ones are around controls that have events that you need to override.  If you need to override the OnFormSave or AfterFormSave of an On-Line Form, it can be done without needing to clone the web part.  Just set it to a type of UI and then create an extender of type BizForm, like the one below:

using CMS;
using CMS.Base.Web.UI;
using CMS.OnlineForms.Web.UI;
using CMS.PortalEngine.Web.UI;
using System.Web.UI.WebControls;
[assembly: RegisterCustomClass("OnlineFormExtender", typeof(OnlineFormExtender))]
public class OnlineFormExtender : ControlExtender<BizForm>
{
    public override void OnInit()
    {
        // Sets a property of the extended page's UniGrid control
        Control.OnAfterSave += Control_OnAfterSave;
    }
 
    private void Control_OnAfterSave(object sender, System.EventArgs e)
    {
        string ToSomethingHere = "";
    }
}

It is also great to allow your own usage of UniSelectors, UniGrids or other tools to be extendable.  I am finishing up a new UI set that heavily used these tools and I added extender capabilities to them all (maybe on the next blog I’ll tell you about it!)

Limitations

There are a couple limitations.  First limitation is that you can only add 1 extender for a control, and a ControlExtender can only be of one type.  So if you have a web part with 2 things you want to extend, you would have to create a Class that you can extend on that exposes the 2 controls (similar to how the UniSelector extender has both the UniSelector and its UniGrid available through its properties).

Conclusion

ControlExtender is another great example of the flexibility that Kentico provides.  They really did a fantastic job of making everything within their system extendable, although there’s so many things that it can impossible to discover all the little nuggets and cool things it can do.
 
Comments
Blog post currently doesn't have any comments.
Is nine = four ? (true/false)
CONTENTEND