Creating a custom WebUITypeEditor

October 27, 2009 Digital Experience
The purpose of this post is to show how you can create a custom WebUITypeEditor. There are a lot of cases, where you would need to extend some base controls and implement a custom logic requiring to get some id or other value from a custom web editor.

This post will show how you can create a custom WebUITypeEditor (selector) for a custom user control. I will use RadTreeView control bound to Sitefinity's CmsSiteMap source. I will return the page's ID as a property value of type Guid. In one of my next posts I will show how to resolve this value and display a page link.

 

First, you should create a user control and in its template you should add Telerik's RadTreeView control.

 

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="PageIDWebEditor.ascx.cs" Inherits="CustomControls_PageIDWebEditor" %> 
 
 
<asp:Label runat="server" ID="Label1" Text="Select a page from the tree" /> 
<telerik:RadTreeView ID="RadTreeView1" runat="server" Skin="Black"/> 
 

In the code behind of this control you need to hook on the NodeDataBound event as you will have to disable the NavigateUrl of each item. Otherwise, when you click on a node, a new page will be opened.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using Telerik.Cms.Web; 
using Telerik.Web.UI; 
 
public partial class CustomControls_PageIDWebEditor : System.Web.UI.UserControl 
    protected void Page_Load(object sender, EventArgs e) 
    { 
        RadTreeView1.NodeDataBound += new Telerik.Web.UI.RadTreeViewEventHandler(RadTeerView1_NodeDataBound); 
    } 
 
    void RadTeerView1_NodeDataBound(object sender, Telerik.Web.UI.RadTreeNodeEventArgs e) 
    { 
        foreach (RadTreeNode node in RadTreeView1.GetAllNodes()) 
        { 
            node.NavigateUrl = ""
        } 
    } 

 

Now that you have completed the template you should create your WebEditor. You should create a custom class that inherits from the WebUITypeEditor of type Guid. You should then implement an abstract class for WebUITypeEditor<Guid>, thus getting the selected Page's id. You should add a new property Template which will be used to specify the template path. To access the RadTreeView control from the template you have to create a control reference. In the CreatechildControls you should create an instance of the CmsManager and Instantiate your template. Afterwards, you should create the RadTreeView nodes using the LoadNodes method .

using System; 
using System.Web.UI; 
using Telerik.Cms; 
using Telerik.Cms.Web.UI; 
using Telerik.Framework.Web; 
using Telerik.Web.UI; 
 
/// <summary> 
/// Summary description for PageIDWebEditor 
/// </summary> 
public class PageIDWebEditor : WebUITypeEditor<Guid> 
    public PageIDWebEditor() 
    { 
    } 
 
    public override Guid Value 
    { 
        get 
        { 
            Guid pageId = Guid.Empty; 
            if (TreeView.SelectedNode != null
                pageId = new Guid(TreeView.SelectedNode.Value); 
            if (pageId != Guid.Empty) 
                return ((ICmsPage)manager.GetPage(pageId)).ID; 
            return Guid.Empty; 
        } 
        set 
        { 
            this.ViewState["selectedPage"] = value; 
             
        } 
    } 
 
    // TEMPLATE PATH  
    public string Templte 
    { 
        get 
        { 
            object o = this.ViewState["Template"]; 
            if (o == null
                return ("~/CustomControls/PageIDWebEditor.ascx"); 
            return (string)o; 
        } 
        set 
        { 
            this.ViewState["Template"] = value; 
        } 
    } 
 
    // CONTROL REFERENCE TO RADTREEVIRE CONTROL 
    protected virtual RadTreeView TreeView 
    { 
        get 
        { 
            return this.Controls[0].FindControl("RadTreeView1"as RadTreeView; 
        } 
    } 
 
    protected override void CreateChildControls() 
    { 
        base.CreateChildControls(); 
        this.manager = new CmsManager(); 
        this.template = ControlUtils.GetTemplate<SelectorTemplate>(this.Templte); 
        this.template.InstantiateIn(this); 
        RadTreeNode root = new RadTreeNode(); 
        root.Value = Guid.Empty.ToString(); 
        root.Text = "AllPages"
        root.Expanded = true
        TreeView.Nodes.Add(root); 
        this.LoadNodes(root); 
    } 
    //HELPER METHOD FOR LOADING OUR NODES 
    private void LoadNodes(RadTreeNode root) 
    { 
            ICmsPage sPage = null
            CmsManager manager = new CmsManager(); 
            foreach (ICmsPage page in manager.GetPages(new Guid(root.Value))) 
            { 
                RadTreeNode node = new RadTreeNode();           
                node.Value = page.ID.ToString(); 
                node.Expanded = true
                node.Text = page.MenuName; 
                node.ToolTip = page.MenuName; 
                root.Nodes.Add(node);          
            } 
             
    } 
    
    public class SelectorTemplate : ITemplate 
    { 
        public void InstantiateIn(Control container) 
        { 
        } 
    } 
 
    private ITemplate template; 
    private CmsManager manager; 
 

 

Finally, you should create a property and declare the WebEditor.

 [WebEditor("PageIDWebEditor, App_Code")] 
    public Guid PageID 
    { 
        get 
        { 
            object obj = this.ViewState["PageID"]; 
            if (obj == null
                return Guid.Empty; 
            return (Guid)obj;  
        } 
        set 
        { 
            this.ViewState["PageID"] = value; 
        } 
    } 

The Progress Team