Tuesday, March 9, 2010

Rounding up minutes to nearest later hour

. Tuesday, March 9, 2010
1 comments

Suppose we need to round up the following data (in minutes) in a SharePoint Column to later hour: -
Time
10
30
60
90
140
Here's how one can go about it.Add a new calculated field and add the following Excel function - ROUNDUP(value, number of digits). Our formula would be - ROUNDUP([Time]/60,0). This would round up the minutes to nearest later hour. Hence result would be: -
Time
10 1
30 1
60 1
90 2
140 3

Monday, February 22, 2010

How to create and deploy a basic Site Definition

. Monday, February 22, 2010
0 comments

A Site Definition provides the underlying structure of a site. It defines the site navigation, available features, document and list templates, initial lists and libraries, webparts available to a site when first created. Site Definitions provide a template for creating sites and can be re-used. Any change to the site definition is reflected across all the sites that are already created and those that shall be created in the future.

Site Definitions differ from site templates that are created by saving a site (non-publishing) as a site template using site settings menu options. Sites created using Site Definitions are ghosted or uncustomized while those created Site templates are un-ghosted or customized. Hence changes to site templates are not reflected in the site already created using them.

Let's have a look at the structural elements of a site definition.

Site definitions are located under 12\Template\SiteTemplates\ folder. It MAY contain following files: -

  1. ONET.XML - located under Site Templates\xml or 2\TEMPLATE\GLOBAL\XML folder. This is the manifest file for the site definition. It is a required file and is used to specify available configurations for a site.
  2. Default.aspx - located under SiteTemplates folder. This file defines the structure of the home page of site created using the site definition.
  3. Default.master - located under 12\Template\Global. It is used by all site definitions.
  4. Schema.xml - located under 12\TEMPLATE\GLOBAL\Lists.  It is used to define the schema (fields) for lists and libraries.
  5. STDVIEW.xml - located under 12\TEMPLATE\GLOBAL\XML. It defines view information for a site.
  6. VWSTYLES.xml - located under 2\TEMPLATE\GLOBAL\XML. It defines view information for lists/libraries.

Now that we've had an overview of various files that constitute a site definition, let's create one basic Site Definition.

  1. Go to 12\Template\Site Templates\ folder. Copy the folder named - STS and paste in a different work folder for custom-projects on your system.
  2. Go to 12\TEMPLATE\1033\XML. Copy WEBTEMP.XML and paste it to the projects work folder created in step1.
  3. Open Visual Studio 2005/2008. Create a new C# class library project named - SoftwareSiteDefinition. We'll create the following structure.
  4. image 
  5. Create above folder structure without creating files. Once done, let's start adding files to them. Go to the folder copied in step 1. open the XML folder within it. Cut-paste ONET.XML file from it to Template\SiteTemplates\SoftwareSiteDefinition\xml\. Cut-paste default.aspx from copied folder in step 1 and paste under Template\SiteTemplates\SoftwareSiteDefinition\.
  6. Now go to the work folder created in step 1. Rename the WEBTEMP.XML file to Webtemp_SoftwareSiteDefinition.xml. Cut-paste this file to Template\1033\XML\ folder in above solution (step 3).
  7. Add a new xml file named - manifest.xml and a text file named- cab.ddf to DeploymentFiles folder. Once we've the files ready, let's start working on them.
  8. Open the Webtemp_SoftwareSiteDefinition.xml file.
  9. paste the below text: -

    <?xml version="1.0" encoding="utf-8"?>
    <!-- _lcid="1033" _version="12.0.4518" _dal="1" -->
    <!-- _LocalBinding -->
    <Templates xmlns:ows="Microsoft SharePoint">
      <Template Name="SoftwareSiteDefinition" ID="11000">
        <Configuration ID="0"
          Title="Software Development Project Site" Hidden="FALSE" ImageUrl="/_layouts/images/stsprev.png"
          Description="A site for managing Software Development projects."
          DisplayCategory="My Custom Templates" >
        </Configuration>
      </Template>
    </Templates>

  10. The name of the template is SoftwareSiteDefinition which should be unique in the 12\template\SiteTemplates folder. This would be the name of the Site definition folder created in above project. They should be identical and this is how the template file associates itself with its site definition.
  11. The configuration element specifies the available configurations/variations within a site definition. There can be multiple configuration elements within Template element. Title attribute specifies the name of configuration as it appears on create new site page. DisplayCategory specifies the tab under which the configuration would be available. Specify a new unique name to create a new tab. Template ID specifies the unique id of site definition. Use values > 10000.
  12. Now open the file - onet.xml from the solution project. We'll make some changes to this definition.
  13. NavBars element is used to specify initial navigation as it appears on the site. One can specify the quick launch navigation as well as top navigation. Paste the below code for navigation.

    <NavBars>
            <NavBar Name="$Resources:core,category_Top;" Separator="&amp;nbsp;&amp;nbsp;&amp;nbsp;" Body="&lt;a ID='onettopnavbar#LABEL_ID#' href='#URL#' accesskey='J'&gt;#LABEL#&lt;/a&gt;" ID="1002"/>
            <NavBar Name="$Resources:core,category_Documents;" Prefix="&lt;table border=0 cellpadding=4 cellspacing=0&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border=0 cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' ID='100' alt='' border=0&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign=top&gt;&lt;a ID=onetleftnavbar#LABEL_ID# href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1004"/>
            <NavBar Name="$Resources:core,category_Lists;" Prefix="&lt;table border=0 cellpadding=4 cellspacing=0&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border=0 cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' ID='100' alt='' border=0&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign=top&gt;&lt;a ID=onetleftnavbar#LABEL_ID# href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1003"/>
            <!--<NavBar Name="$Resources:core,category_Discussions;" Prefix="&lt;table border=0 cellpadding=4 cellspacing=0&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border=0 cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' ID='100' alt='' border=0&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign=top&gt;&lt;a ID=onetleftnavbar#LABEL_ID# href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1006"/>-->
            <NavBar Name="$Resources:core,category_Sites;" Prefix="&lt;table border=0 cellpadding=4 cellspacing=0&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border=0 cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' ID='100' alt='' border=0&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign=top&gt;&lt;a ID=onetleftnavbar#LABEL_ID# href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1026"/>
            <NavBar Name="$Resources:core,category_People;" Prefix="&lt;table border=0 cellpadding=4 cellspacing=0&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border=0 cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' ID='100' alt='' border=0&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign=top&gt;&lt;a ID=onetleftnavbar#LABEL_ID# href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1027"/>
        <NavBar Name="Quick Links" Prefix="&lt;table border=0 cellpadding=4 cellspacing=0&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border=0 cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' ID='100' alt='' border=0&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign=top&gt;&lt;a ID=onetleftnavbar#LABEL_ID# href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1028">
          <NavBarLink Name="Google Chart" Url="
    http://code.google.com/apis/chart/" />
          <NavBarLink Name="Heather Solomon" Url="
    http://www.heathersolomon.com/blog/articles/MOSS07DesignComponents.aspx"/>
        </NavBar>

  14. As we can see, I have commented the discussions link from quick launch, since I don't want this list to appear. I also don't want this list to be create by default ( this'll be taken care of in later sections). I have also added a new navigation heading named - Quick Links which has two hyperlinks.
  15. Now go to the configuration section, remove all configurations but the one with ID=0.

    <Lists>
                    <List FeatureId="00BFEA71-E717-4E80-AA17-D0C71B360101" Type="101" Title="$Resources:core,shareddocuments_Title;" Url="$Resources:core,shareddocuments_Folder;" QuickLaunchUrl="$Resources:core,shareddocuments_Folder;/Forms/AllItems.aspx"/>
                    <!--<List FeatureId="00BFEA71-6A49-43FA-B535-D15C05500108" Type="108" Title="$Resources:core,discussions_Title;" Url="$Resources:core,lists_Folder;/$Resources:core,discussions_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,discussions_Folder;/AllItems.aspx" EmailAlias="$Resources:core,discussions_EmailAlias;"/>-->
                    <!--
            <List FeatureId="00BFEA71-D1CE-42de-9C63-A44004CE0104" Type="104" Title="$Resources:core,announceList;" Url="$Resources:core,lists_Folder;/$Resources:core,announce_Folder;">
                        <Data>
                            <Rows>
                                <Row>
                                    <Field Name="Title">$Resources:onetid11;</Field>
                                    <Field Name="Body">$Resources:onetid12;</Field>
                                    <Field Name="Expires">&lt;ows:TodayISO/&gt;</Field>
                                </Row>
                            </Rows>
                        </Data>
                    </List>
            -->
                    <List FeatureId="00BFEA71-2062-426C-90BF-714C59600103" Type="103" Title="$Resources:core,linksList;" Url="$Resources:core,lists_Folder;/$Resources:core,links_Folder;"/>
                    <List FeatureId="00BFEA71-EC85-4903-972D-EBE475780106" Type="106" Title="$Resources:core,calendarList;" Url="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;/Calendar.aspx" EmailAlias="$Resources:core,calendar_EmailAlias;"/>
                    <List FeatureId="00BFEA71-A83E-497E-9BA0-7A5C597D0107" Type="107" Title="$Resources:core,taskList;" Url="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;/AllItems.aspx"/>
                </Lists>

  16. I have commented the discussions and announcement list section, since I don't want it to appear in the pre-created lists. Remember that if a list is not created initially, it's references should also be removed from quick launch navigation.
  17. Remove all modules child elements of configuration element except the one named - Default. Now go to the Modules element which is a child element of Project and not configuration element. remove all modules except- Default.

    <Module Name="Default" Url="" Path="">
                <File Url="default.aspx" NavBarHome="True">
            <View List="$Resources:core,shareddocuments_Folder;" BaseViewID="0"  WebPartZoneID="Top" WebPartOrder="2"/>
                    <!--<View List="$Resources:core,lists_Folder;/$Resources:core,announce_Folder;" BaseViewID="0" WebPartZoneID="Left"/>-->
                    <View List="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;" BaseViewID="0" RecurrenceRowset="TRUE" WebPartZoneID="Left" WebPartOrder="2"/>
                    <AllUsersWebPart WebPartZoneID="Right" WebPartOrder="1"><![CDATA[
                       <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2" xmlns:iwp="http://schemas.microsoft.com/WebPart/v2/Image">
                            <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
                            <TypeName>Microsoft.SharePoint.WebPartPages.ImageWebPart</TypeName>
                            <FrameType>None</FrameType>
                            <Title>$Resources:wp_SiteImage;</Title>
                            <iwp:ImageLink>/_layouts/images/homepage.gif</iwp:ImageLink>
                            <iwp:AlternativeText>$Resources:core,sitelogo_wss;</iwp:AlternativeText>
                       </WebPart>
                       ]]></AllUsersWebPart>
                    <View List="$Resources:core,lists_Folder;/$Resources:core,links_Folder;" BaseViewID="0" WebPartZoneID="Right" WebPartOrder="2"/>
                    <NavBarPage Name="$Resources:core,nav_Home;" ID="1002" Position="Start"/>
                    <NavBarPage Name="$Resources:core,nav_Home;" ID="0" Position="Start"/>
                </File>
            </Module>

  18. This element will specify the views appearing on the home page and the navigations. Add a new view for - Shared Documents list. Ensure that the list is created in advance (step 15). Comment the announcement list view. Save the file.
  19. Now open default.aspx from the project.
  20. Add a new data row for containing a webpart zone which will span all the rows below.

    <table width="100%" cellpadding=0 cellspacing=0 style="padding: 5px 10px 10px 10px;">
              <tr>
               <td valign="top" width="100%" colspan="3">
                   <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Top" Title="loc:Top" />
                   &nbsp;
               </td>
               </tr>
              <tr>
               <td valign="top" width="70%">
                   <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Left" Title="loc:Left" />
                   &nbsp;
               </td>
               <td>&nbsp;</td>
               <td valign="top" width="30%">
                   <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Right" Title="loc:Right" />
                   &nbsp;
               </td>
               <td>&nbsp;</td>
              </tr>
             </table>
            </td>
          </tr>
        </table>

  21. Save the file.

Once the site definition is created, we need to create a deploy package for it.

Creating the WSP/solution package for Site definition

  1. open manifest.xml and make following entries.

    <?xml version="1.0" encoding="utf-8" ?>
    <Solution xmlns="http://schemas.microsoft.com/sharepoint/" SolutionId="0C07DA61-1542-4d49-BA09-2587B4125A63"
               DeploymentServerType="WebFrontEnd"
               ResetWebServer="False">
      <SiteDefinitionManifests>
        <!-- name of root folder of manifest of site definition within the WSP-->
        <SiteDefinitionManifest Location="SoftwareSiteDefinition">
          <!-- complete path of webtemp file within this solution package-->
          <WebTempFile Location="1033\XML\Webtemp_SoftwareSiteDefinition.xml"/>
        </SiteDefinitionManifest>
      </SiteDefinitionManifests>
    </Solution>

  2. Rt. click the file, select properties. Select the schema which should be WSS.xsd (xmlns=http://schemas.microsoft.com/sharepoint/) located in 12\template\xml.
  3. This file specifies the name of associated files. SiteDefinitionManifest Location specifies the name of the root folder of site definition within the WSP package. WebTempFile Location specifies the location and name of the webtemp files within the WSP package. hence the path is relative to WSP and not 12 hive.
  4. save the file and open cab.ddf. This is a diamond directive file.
  5. Paste the following.

    ;****** this file packages the files from solution to WSP
    .OPTION Explicit
    .Set Cabinet=On
    .Set CabinetNameTemplate=SoftwareSiteDefinition.wsp;****name of the wsp file
    .Set CompressionType=MSZIP
    .Set DiskDirectory1=MYWSP
    .Set DiskDirectoryTemplate=CDROM
    .Set UniqueFiles=Off

    ;*** include location of WSP manifest from root of the solution
    DeploymentFiles\manifest.xml

    ;*** include locations of onet,default.aspx and webtemp
    ;*** create subfolder within the WSP

    .Set DestinationDir=SoftwareSiteDefinition
    Template\SiteTemplates\SoftwareSiteDefinition\default.aspx

    .Set DestinationDir=SoftwareSiteDefinition\xml
    Template\SiteTemplates\SoftwareSiteDefinition\xml\onet.xml

    .Set DestinationDir=1033\XML
    Template\1033\XML\Webtemp_SoftwareSiteDefinition.xml

  6. We need to place all the necessary files from the solution project to the package so that they could be picked up by manifest.xml.
  7. The package will have following structure: - Two folders with following hierarchies.
  8. SoftwareSiteDefinition
    1. default.aspx
    2. xml
      1. onet.xml
  9. 1033
    1. XML
      1. Webtemp_SoftwareSiteDefinition.xml
  10. DeploymentFiles\manifest.xml
  11. DestinationDir allows us to create subfolders within the package. The locations below it specify the actual location of all four files within the project solution. save the file
  12. Go to command prompt. Browse to the root folder e.g. C:\SharepointCustomProjects\SoftwareSiteDefinition\SoftwareSiteDefinition.
  13. un makecab /f DeploymentFiles\manifest.xml. This will create a  package named - MYWSP under the root of the project which will contain a WSP cabinet file named - SoftwareSiteDefinition.wsp.

 

Sources:

Microsoft SharePoint Building office 2007 solutions in C# 2005 - Scot Hillier (APRESS).

Professional SharePoint 2007 Web Content Management Development - Andrew Connell (WROX)

Saturday, July 18, 2009

Enumerate SharePoint Features

. Saturday, July 18, 2009
0 comments

Enumerate Installed Features in the Farm

TreeView TreeView1 = new TreeView();

TreeView1.Nodes.Add(new TreeNode("Features"));
TreeNode oFSiteNode = null;
TreeNode oFNode = null;

SPSecurity.RunWithElevatedPrivileges(delegate()
{

//get the name of the current web in current user's context

                string spSiteURL = SPControl.GetContextSite(Context).Url.ToString();

                //Initialize the spweb object using the elevated privileges
                using (SPSite oSite = new SPSite(spSiteURL))
                {


TreeView1.Nodes.Clear();

#region Return Installed Features.

                    oFSiteNode = new TreeNode("All Farm Installed Features");

                    SPFarm oFarm = oSite.WebApplication.Farm;

                    SPFeatureDefinitionCollection oFeatDefColl = oFarm.FeatureDefinitions;
                    foreach (SPFeatureDefinition oFeatDef in oFeatDefColl)
                    {
                        if (oFeatDef != null)
                        {
                            oFNode = new TreeNode(oFeatDef.GetTitle(new System.Globalization.CultureInfo(1033)));
                            oFSiteNode.ChildNodes.Add(oFNode);
                        }
                    }

                    TreeView1.Nodes[1].ChildNodes.Add(oFSiteNode);

#endregion

TreeView1.CollapseAll();
oSite.Dispose();

}

}

Enumerate Site collection and Site Content Types

.
0 comments

I will be creating a web part that enumerates root site and all it's subsites content types along with their columns.

We will be using a Tree View control for this.

using System;
using System.Collections.Generic;
using System.Text;

using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.WebControls;

/// <summary>
        /// Shows content types recursively
        /// </summary>
        /// <param name="oWeb">The parent node</param>
        /// <param name="oNode">The content Type node</param>
        protected void ShowCTypes(SPWeb oWeb, TreeNode oNode, SPContentTypeId contTypeID)
        {
            TreeNode oSubNode = null;
            SPContentTypeCollection oCTypeColl = oWeb.ContentTypes;

            foreach (SPContentType conttype in oCTypeColl)
            {
                //if current type is child of parameter oNode and is not the root ctype
                if (conttype.Parent.Id == contTypeID && conttype.Parent.Id != conttype.Id)
                {
                    oSubNode = new TreeNode(conttype.Name);
                    oSubNode.NavigateUrl = oWeb.ServerRelativeUrl + "/_layouts/ManageContentType.aspx?cType=" + conttype.Id;
                    oSubNode.Target = "_blank";

                    //add columns
                    ShowCtypeColumns(oSubNode, conttype);
                    //add subnodes
                    oNode.ChildNodes.Add(oSubNode);

                    //now oSubNode is the parent node
                    ShowCTypes(oWeb, oSubNode, conttype.Id);
                }
            }

        }

        /// <summary>
        /// Shows columns for a content type
        /// </summary>
        /// <param name="oNode">Current content type Treenode</param>
        /// <param name="contType">Content type whose columns are to be added</param>
        protected void ShowCtypeColumns(TreeNode oNode, SPContentType contType)
        {
            TreeNode oSubNode = null;

            //fetch fields of content type
            SPFieldCollection oFldColl = contType.Fields;

            if (oFldColl.Count != 0)
                oNode.ChildNodes.Add(new TreeNode("Columns"));

            foreach (SPField oField in oFldColl)
            {
                if (!oField.Title.Equals("ContentType") && !oField.Hidden)
                {
                    oSubNode = new TreeNode(oField.Title);
                    oSubNode.NavigateUrl = contType.ParentWeb.ServerRelativeUrl + "/_layouts/ManageContentTypeField.aspx?cType=" + contType.Id + "&Field=" + oField.InternalName + "&Fid=" + oField.Id;
                    oSubNode.Target = "_blank";
                    oNode.ChildNodes[0].ChildNodes.Add(oSubNode);
                }
            }

        }

/// <summary>
        /// Creates Treeview nodes for content types and features.
        /// </summary>
        protected void CreateControls()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                TreeView1.Nodes.Clear();
                TreeView1.Nodes.Add(new TreeNode("Content Types"));

                //get the name of the current web in current user's context

                string spSiteURL = SPControl.GetContextSite(Context).Url.ToString();

                //Initialize the spweb object using the elevated privileges
                using (SPSite oSite = new SPSite(spSiteURL))
                {
                    SPWebCollection oWebColl = oSite.AllWebs;

                    #region Add content types

                    TreeNode oSiteNode = null;
                    foreach (SPWeb oWeb in oWebColl)
                    {
                        //create website nodes
                        oSiteNode = new TreeNode(oWeb.Title);
                        oSiteNode.NavigateUrl = oWeb.Url;

                        //get contenttypes collection for each subsite including root site
                        SPContentTypeCollection oCTypeColl = oWeb.ContentTypes;
                        TreeNode oNode = new TreeNode();

                        //if site doesn't have any Ctypes (only content types defined for that particular site are displayed)
                        if (oCTypeColl.Count != 0)
                        {
                            oNode.Text = oCTypeColl[0].Name;
                            oNode.NavigateUrl = oWeb.ServerRelativeUrl + "/_layouts/ManageContentType.aspx?cType=" + oCTypeColl[0].Id.ToString();
                            oNode.Target = "_blank"; //opens link in new window

                            //send current site and root contenttype node (not the actual content type)
                            ShowCTypes(oWeb, oNode, oCTypeColl[0].Id);

                            //add root contenttype node to website node
                            oSiteNode.ChildNodes.Add(oNode);

                        }
                        //add website node to root node of treeview.
                        TreeView1.Nodes[0].ChildNodes.Add(oSiteNode);
                        oWeb.Dispose();
                    }
                    #endregion

 

TreeView1.CollapseAll();
                    oSite.Dispose();
                }
            } //end of delegate
            ); //end of RunWithElevatedPrivileges

        }

        protected override void OnPreRender(EventArgs e)
        {
            CreateControls();
        }

        protected override void CreateChildControls()        {
            //add control to treeview
            this.Controls.Add(TreeView1);
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            //render treeview control
            TreeView1.RenderControl(writer);
        }

    }
}