Integrating 3rd party components in Kentico CMS – Component Art TreeView
Example of integrating ComponentArt TreeView. This article describes how to add a 3rd party sitemap control in Kentico CMS. In this example we will add a TreeView control from ComponentArt.
At first, you will need to download and install
Web.UI 2008.2 for ASP.Net (registration required). You can choose there from 4 different platform builds, we were working with ASP .NET 3.5 build in this example so we recommend to use same build to ensure compatibility. You can either use the trial mode or you can buy the components from ComponentArt.
After the installation you can find (typically) in
c:\Program Files\ComponentArt\Web.UI 2008.2 for ASP.NET 3.5\ this DLL file
ComponentArt.Web.UI.dll. Please copy this file to you web project’s BIN folder. Now you are ready to develop custom site map web part (control) using the ComponentArt. Please follow these steps:
Open the web project in Visual Studio and follow this description how to
create new web part (please do not forget to change the inherited class to
CMSAbstractWebPart).
In the Toolbox you can find added new controls from ComponentArt. Please drag the TreeView control and drop it to the ascx code of your control. Switch to the code behind.
We use same practice as in our previous article which was dealing with integrating Component Art menu control and we will some properties object, to ensure the control will be able to handle some properties:
// MenuProperties object - ensures the data integrity and provides GroupedDataSource
CMSMenuProperties properties = new CMSMenuProperties();
Now you can add to your control some common and recommended properties like
ClassNames (document types),
CombineWithDefaultCulture, CultureCode, MaxRelativeLevel, OrderBy, Path, SelectOnlyPublished, SiteName, WhereCondition and
FilterControl. For example:
///<summary>
/// Gets or sets the nodes path
///</summary>
public string Path
{
get
{
return DataHelper.GetNotEmpty(ValidationHelper.GetString(this.GetValue("Path"), this.properties.Path), this.properties.Path);
}
set
{
this.SetValue("Path", value);
this.properties.Path = value;
}
}
You should use same practice to create custom properties connected with settings and design of TreeView control. To store these properties in database appropriate webpart properties in properties tab of your custom webpart in
SiteManager->Development->Webparts should be created.
The main logic of the control is performed in
SetupControl() method. If you have defined the properties, you need to initialize them in this method:
///<summary>
/// Initializes the control properties
///</summary>
protected void SetupControl()
{
if (this.StopProcessing)
{
this.properties.StopProcessing = true;
}
else
{
// Initialize the CMSMenuProperties object
properties.ParentControl = this;
properties.Path = this.Path;
properties.WhereCondition = this.WhereCondition;
properties.SiteName = this.SiteName;
properties.SelectOnlyPublished = this.SelectOnlyPublished;
properties.OrderBy = this.OrderBy;
properties.CultureCode = this.CultureCode;
properties.CombineWithDefaultCulture = this.CombineWithDefaultCulture;
properties.ClassNames = this.ClassNames;
properties.MaxRelativeLevel = this.MaxRelativeLevel;
properties.CacheMinutes = this.CacheMinutes;
properties.CacheItemName = this.CacheItemName;
properties.CheckPermissions = this.CheckPermissions;
properties.CacheDependencies = this.CacheDependencies;
properties.DataSource = properties.GetDataSource();
}
}
Now, you will need to create new methods which will help with creating and populating the items. For example:
///<summary>
/// Creates new Instance of TreeView Node from node DataRow
///</summary>
///<param name="dr">DataRow with node data</param>
///<returns>New instance of TreeViewNode</returns>
private ComponentArt.Web.UI.TreeViewNode CreateItem(DataRow dr)
{
string imageUrl;
ComponentArt.Web.UI.TreeViewNode Node = new ComponentArt.Web.UI.TreeViewNode();
// Set menu caption
Node.Text = GetMenuText(dr);
// Choose node image URL
if (this.DisplayDocumentTypeImages)
{
imageUrl = GetDocumentTypeImage(dr);
if (imageUrl.Length != 0)
{
Node.ImageUrl = imageUrl;
Node.SelectedExpandedImageUrl = imageUrl;
Node.ExpandedImageUrl = imageUrl;
}
}
// Set nodes URL
if (this.SetNodeURL)
{ Node.NavigateUrl = GetURL(dr); }
// Hiding documents according to setting in properties
if (this.HideInNavigation)
{
if (Convert.ToBoolean(dr["DocumentMenuItemHideInNavigation"]))
{
Node.Visible = false;
}
}
return Node;
}
and
///<summary>
/// Populates (recursively) the specified Tree view node with its subitems
///</summary>
///<param name="parentNodeId">NodeID of the node to be populated</param>
///<param name="parent">TreeViewNode to be populated with subitems</param>
private void PopulateTreeItem(int parentNodeId, ComponentArt.Web.UI.TreeViewNode parent)
{
// Get child items from GroupedDataSource object
ArrayList items = properties.GroupedDS.GetGroup(parentNodeId);
if (items != null )
{
// Append all childs
foreach (DataRow dr in items)
{
// Get menu item nodeid (to get the child items)
int nodeId = ValidationHelper.GetInteger(dr["NodeID"], 0);
// Create tree view node, add it to tree and populate it with subitems
ComponentArt.Web.UI.TreeViewNode child = CreateItem(dr);
parent.Nodes.Add(child);
if (!this.CurrentTreeViewNodeFound && ValidationHelper.GetString(dr["NodeGUID"], "") == CMS.CMSHelper.CMSContext.CurrentDocument.NodeGUID.ToString())
{ // expand current path
if (this.ExpandCurrentPath)
{
this.ExpandParentNodes(child.ParentNode);
}
// expand sub tree
if (this.ExpandSubTree)
{
child.Expanded = true;
}
this.CurrentTreeViewNodeFound = true;
}
// Populate resursively tree
PopulateTreeItem(nodeId, child);
}
}
}
As you can see, second method is recursively calling itself and also the
CreateItem method. This ensures that all items are properly populated.
Next step is to create a method which will use mentioned two methods to build whole TreeView tree structure:
///<summary>
/// Generates Tree view node tree structure from dataset
///<param name="ds">DataSet with nodes data</param>
///</summary>
private void GenerateTree(DataSet ds)
{
// Get top node level
if (ds.Tables[0].Rows.Count != 0)
{
int topNodeLevel = ValidationHelper.GetInteger(ds.Tables[0].Rows[0]["NodeLevel"], 0);
// Get all the items in the top level
foreach (DataRow dr in ds.Tables[0].Rows)
{
if (ValidationHelper.GetInteger(dr["NodeLevel"], 0) == topNodeLevel)
{
// Get node nodeid (to get the child items)
int nodeId = ValidationHelper.GetInteger(dr["NodeID"], 0);
// Create tree view node, add it to tree view and populate it with subitems
ComponentArt.Web.UI.TreeViewNode child = CreateItem(dr);
this.TreeView1.Nodes.Add(child);
// Expand if node is in current path
if (!this.CurrentTreeViewNodeFound && ValidationHelper.GetString(dr["NodeGUID"], "") == CMS.CMSHelper.CMSContext.CurrentDocument.NodeGUID.ToString())
{
//expand sub tree
if (this.ExpandSubTree)
{
child.Expanded = true;
this.CurrentTreeViewNodeFound = true;
}
this.TreeView1.SelectedNode=child;
}
// Populate resursively tree
PopulateTreeItem(nodeId, child);
}
}
}
}
Finally method
SetTreeViewProperties is created to set properties of Component Art TreeView control and to assign created tree structure to this control.
///<summary>
/// Generates Tree view tree structure and set its properties
///<param name="ds">DataSet with nodes data</param>
///</summary>
private void SetTreeViewProperties(DataSet ds)
{
// Generate tree structure
GenerateTree(ds);
// Set TreeView properties
this.TreeView1.CssClass = this.MainCssClass;
this.TreeView1.NodeCssClass = this.NodeCssClass;
this.TreeView1.NodeRowCssClass = this.NodeRowCssClass;
this.TreeView1.SelectedNodeCssClass = this.SelectedNodeCssClass;
this.TreeView1.HoverNodeCssClass = this.HoverNodeCssClass;
// Set URL of node images
if (!this.DisplayDocumentTypeImages)
{ this.TreeView1.ImagesBaseUrl = this.ImagesBaseUrl;
this.TreeView1.ParentNodeImageUrl = this.ParentNodeImageUrl;
this.TreeView1.ExpandedParentNodeImageUrl = this.ExpandedParentNodeImageUrl;
this.TreeView1.LeafNodeImageUrl = this.LeafNodeImageUrl;
}
else
{
this.TreeView1.ParentNodeImageUrl = this.ImagesBaseUrl + '/' + this.ParentNodeImageUrl;
this.TreeView1.ExpandedParentNodeImageUrl = this.ImagesBaseUrl + '/' + this.ExpandedParentNodeImageUrl;
this.TreeView1.LeafNodeImageUrl = this.ImagesBaseUrl + '/' + this.LeafNodeImageUrl;
}
this.TreeView1.ParentNodeImageUrl = this.ParentNodeImageUrl;
this.TreeView1.ExpandedParentNodeImageUrl = this.ExpandedParentNodeImageUrl;
this.TreeView1.LeafNodeImageUrl = this.LeafNodeImageUrl;
this.TreeView1.ShowLines = this.ShowLines;
this.TreeView1.LineImagesFolderUrl = this.LineImagesFolderUrl;
this.TreeView1.ExpandImageUrl = this.ExpandImageUrl;
this.TreeView1.CollapseImageUrl = this.CollapseImageUrl;
this.TreeView1.NoExpandImageUrl = this.NoExpandImageUrl;
this.TreeView1.CollapseDuration = this.CollapseDuration;
this.TreeView1.ExpandDuration = this.ExpandDuration;
this.TreeView1.CollapseSlide = (SlideType)this.CollapseSlide;
this.TreeView1.ExpandSlide = (SlideType)this.ExpandSlide;
// Expand all nodes
if (this.ExpandAllOnStartup)
{
this.TreeView1.ExpandAll();
}
}
This method is used in
OnLoad event to ensure proper function of new feature included in version 4.0, data filtering:
///<summary>
/// OnLoad
///</summary>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//Set the filter to TreeView
if (this.FilterControl != null)
{
this.FilterControl.InitDataProperties(this.properties);
}
// Set TreeView properties
SetTreeViewProperties(properties.GetDataSource());
}
You can download the complete code example from
here. In the package are included sample CSS styles and web part properties and this KB article as well. Webpart is included in the zip package in the form of exported objects package, so you can
import it to your CMS (package is prepared for 4.0 version) and then use it in your site and view the code in Visual Studio. The controls are imported to the
ComponentArt folder under
CMSWeparts.
See also: Applies to: Kentico CMS 4.0, ComponentArt