In NavigationWebPart.cs,
we’ll remove some additional code that has been added by the template
before we create our properties. Remove all the generated comments and
the following:
private const string defaultText = "";
private string text = defaultText;
[Browsable(true),
Category("Miscellaneous"),
DefaultValue(defaultText),
WebPartStorage(Storage.Personal),
FriendlyName("Text"),
Description("Text Property")]
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
Also remove this auto-generated line from the RenderWebPart() method:
Output.Write(SPEncode.HtmlEncode(Text));
Then add the import for the System.Web namespace, and NavigationWebPart.cs should now look like this:
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
namespace ExtensibleMCMSPageListingWebPart
{
[ToolboxData("<{0}:NavigationWebPart
runat=server></{0}:NavigationWebPart>"),
XmlRoot(Namespace="ExtensibleMCMSPageListingWebPart")]
public class NavigationWebPart : Microsoft.SharePoint.WebPartPages.WebPart
{
/// <summary>
/// Render this Web Part to the output parameter specified.
/// </summary>
/// <param name="output"> The HTML writer to write out to </param>
protected override void RenderWebPart(HtmlTextWriter output)
{
}
}
}
At the top of the class, we need to declare two enumerations that will be used throughout the class. The first enumeration is enmMode,
which will facilitate troubleshooting of the new Web Part. There will
be four different modes for testing different functionality:
DebugShowXml—the Web Part will dump the XML data received from MCMS so the user may review it.
DebugWithTestData—allows the user to test the XSLT by showing preconfigured test data together with the currently configured XSLT stylesheet.
DebugShowException—used
to test the actual MCMS data together with the current configured
stylesheet. If exceptions occur, they will be displayed in clear
text—something you would avoid on a production site.
Production—similar to DebugShowException but hides the exception details and displays a friendly error message.
#region declarations - enumerations, constants and private variables
// The mode of the Web Part used for troubleshooting and exception handling.
public enum enmMode
{
DebugWithTestData, // Render the Web Part using the XSLT and TestXml
DebugShowXml, // Output the XML
DebugShowException, // If an exception is thrown return the details
Production // Mode for running in production, suppress error
// messages.
}
The second enumeration, enmSortBy, specifies the sort order of the channel items returned by MCMS:
public enum enmSortBy
{
Default, // No Sort
ChangeDate,
DisplayName,
DisplayPath,
ExpiryDate,
Importance,
Ordinal,
StartDate
}
#endregion
In the next step, we
define the custom properties for the Web Part. Each public property will
get and set a private variable and will also have a default value. The
following table shows the Web Part Framework attributes assigned to each
of the public properties:
Attribute Name | Description |
---|
Browsable | Must be set to True for the custom property to appear in the ToolPane. |
Category | Defines the grouping in the ToolPane. If this value is left empty or is not defined, the category will be Custom Properties. |
DefaultValue | The value of the Web Part will be stored in the Web Part storage system if it differs from this attribute. |
Description | The tooltip that will be displayed over the friendly name in the ToolPane. |
FriendlyName | The name that will be displayed in the ToolPane. |
ReadOnly | If this is set to True, the custom property will be displayed in the ToolPane but the user will be unable to modify it. |
WebPartStorageAttribute | Custom properties can be stored at a per-user level by setting this to Storage.Personal or on a global level by using Storage.Shared. If it is set to Storage.None the value will not be stored in the Web Part storage system and the property will not appear in the ToolPane. |
Required properties for our Web Part are the mode it should be running in (Mode), the column to use for sorting (SortBy), the channel that should be enumerated (StartChannel), and a property to define the XSLT stylesheet to be used for rendering (PresentationXsl).
We’ll also have a property (TestXml) that is only used in DebugWithTestData mode. This property will allow us to configure the test XML data to be used when debugging the XSLT stylesheet.
#region properties
// Declare the private variables for the Mode property
// By default we run the Web Part in Production mode (suppressing exceptions)
const NavigationWebPart.enmMode _ModeDefault =
NavigationWebPart.enmMode.Production;
private NavigationWebPart.enmMode _Mode = _ModeDefault;
// Set the attributes for the property
[ Browsable(true) ]
[ Category("MCMS Listing Mode") ]
[ DefaultValue(_ModeDefault) ]
[ Description("The mode of the Webpart.") ]
[ FriendlyName("Mode") ]
[ WebPartStorageAttribute(Storage.Shared) ]
public NavigationWebPart.enmMode Mode
{
get{ return _Mode; }
set{ _Mode = value; }
}
The SortBy property sets the sort order of the channel items returned by MCMS. By default the channel items will be sorted by ordinal.
// Declare the start channel private variables
const NavigationWebPart.enmSortBy _SortByDefault =
NavigationWebPart.enmSortBy.Ordinal;
private NavigationWebPart.enmSortBy _SortBy = _SortByDefault;
// Set the attributes for the property
[ Browsable(true) ]
[ Category("MCMS Listing Configuration") ]
[ DefaultValue(_SortByDefault) ]
[ Description("The Sort order of the Webpart.") ]
[ FriendlyName("Sort By") ]
[ WebPartStorageAttribute(Storage.Shared) ]
public NavigationWebPart.enmSortBy SortBy
{
get{ return _SortBy; }
set{ _SortBy = value; }
}
The StartChannel property sets the path of the channel whose child items (channels and/or postings) we will list:
// Declare the start channel private variables, default is /Channels/
const string _StartChannelDefault = "/Channels/";
private string _StartChannel = _StartChannelDefault;
// Set the attributes for the property
[ Browsable(true) ]
[ Category("MCMS Listing Configuration") ]
[ DefaultValue(_StartChannelDefault) ]
[ Description("The channel to list the child items of.") ]
[ FriendlyName("Start Channel") ]
[ WebPartStorageAttribute(Storage.Shared) ]
public string StartChannel
{
get{ return _StartChannel; }
set{ _StartChannel = value; }
}
The next two properties we will add are the TestXml and PresentationXsl properties. Both properties will load data from a file stored in the Web Part resources folder (wpresources)
if their value is not set. This ensures that the Web Part will have a
default XSLT stylesheet and XML test data present when it is first added
to a page:
// Declare the Presentation XSLT private variables
// Default is empty because we will load from a file
const string _PresentationXslDefault = "";
private string _PresentationXsl = _PresentationXslDefault;
// Set the attributes for the property
[ Browsable(true) ]
[ Category("MCMS Listing Presentation") ]
[ DefaultValue(_PresentationXslDefault) ]
[ Description("The XSLT the MCMS listing will display.") ]
[ FriendlyName("Presentation Xslt") ]
[ WebPartStorageAttribute(Storage.Shared) ]
public string PresentationXsl
{
get
{
if (_PresentationXsl == "")
{
// load XSLT from the wpresources folder if _PresentationXsl not set
string XslFile = "/wpresources/ExtensibleMCMSPageListingWebPart/"
+ "DefaultXsl.xslt";
try
{
System.Xml.XmlDocument _doc = new System.Xml.XmlDocument();
// Get the path of the DefaultXsl.xslt that is stored in
// /wpresources/ExtensibleMCMSPageListingWebPart/
_doc.Load(HttpContext.Current.Server.MapPath(XslFile));
// Set the local variable to be the string representation
// of the XSL file
_PresentationXsl = _doc.OuterXml;
}
catch
{
_PresentationXsl = "Failed to load from "
+ HttpContext.Current.Server.MapPath(XslFile);
}
}
return _PresentationXsl;
}
set{ _PresentationXsl = value; }
}
// Declare the TestXsl private variables
const string _TestXmlDefault = "";
private string _TestXml = _TestXmlDefault;
// Set the attributes for the property
[ Browsable(true) ]
[ Category("MCMS Listing Presentation") ]
[ Description("The Xml to be parsed for testing when in debug mode.") ]
[ FriendlyName("Test XML") ]
[ WebPartStorageAttribute(Storage.Shared) ]
[ DefaultValue(_TestXmlDefault) ]
public string TestXml
{
get
{
if (_TestXml == "")
{
// load XML from the wpresources folder if _ TestXml not set
string XmlFile = "/wpresources/ExtensibleMCMSPageListingWebPart"
+ "/TestXml.xml";
try
{
System.Xml.XmlDocument _doc = new System.Xml.XmlDocument();
// Get the path of the TestXml.xml that is stored in
// /wpresources/ExtensibleMCMSPageListingWebPart/
_doc.Load(HttpContext.Current.Server.MapPath(XmlFile));
// Set the local variable to be the string representation
// of the XML file.
_TestXml = _doc.OuterXml;
}
catch
{
_TestXml = "Failed to load from "
+ HttpContext.Current.Server.MapPath(XmlFile);
}
}
return _TestXml;
}
set{ _TestXml = value; }
}
#endregion
For code manageability, use #region and #endregion to effectively organize sections of your code files in Visual Studio .NET.