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; |
| } |
| } |