Thursday, April 05, 2012

Dynamically creating Site Action Menu using .Net Code Behind in SharePoint 2010


Hello friends,
Previously I explained how to create menus using SharePoint ASPMenu (here). This SharePoint ASPMenu we can customize as per our requirement. SharePoint ASPMenu gives us control on look and feel of a menu and also easy to control using CSS.

Sometimes we want to create menus which will look similar to the Site Action Menu. There are several articles on how we can customize the Site Action Menu with features. Using features it is possible to add/remove the menu items in Site Action Menus.

It is possible to create a new menu using the SiteAction Server Control. We can add and remove menus dynamically in control. This will take the default css property to render the menu control just like Site Action Menu Control.
Here in below case study, we want to create a menu which will look similar to the Site Action Menu but with following option.
Step1: Create an xml file which will have all options defined under "File Actions" menu. (FileActions.xml)
<FileActions>
<MenuItems>
<MenuItem ID="1" MenuText="Draft" MenuDesc="Save a draft copy of article" MenuImage="/_layouts/images/edit.gif"
MenuURL="/_Layouts/EC.Application/Pages/SaveArticle.aspx?Action=Draft" Width="500" Height="400">
</MenuItem>
<MenuItem ID="2" MenuText="Publish" MenuDesc="Publish article to internet" MenuImage="/_layouts/images/edit.gif"
MenuURL="/_Layouts/EC.Application/Pages/SaveArticle.aspx?Action=Publish" Width="500" Height="400">
</MenuItem>
<MenuItem ID="3" MenuText="Close" MenuDesc="Close article" MenuImage="/_layouts/images/edit.gif"
MenuURL="/_Layouts/EC.Application/Pages/SaveArticle.aspx?Action=Close" Width="500" Height="400">
</MenuItem>
</MenuItems>
</FileActions>

Step 2: Create a User control FileActionsMenuControl in Sharepoint Mapped folder ControlTemplate.




Step 3: Add ascx html.
<SharePoint:ActionsMenu id="FileActions" runat="server">
<CustomTemplate>
</CustomTemplate>
</SharePoint:ActionsMenu>

Step 4: Add code behind which will connect to the XML created in Step1 to retrieve the details of each menu to add under FileActions Menu class.
#region [Constants/Read Only Variables]
XName xnContactUsMenu = "MenuItem";
XName menuID = "ID";
XName menuText = "MenuText";
XName menuDesc = "MenuDesc";
XName menuImage = "MenuImage";
XName menuURL = "MenuURL";
XName modalWidth = "Width";
XName modalHeight = "Height";

const string MENUTEXT = "File Actions";
const string MENUCSSCLASS = "ms-SPLink ms-SpLinkButtonInActive ms-welcomeMenu";
const string HOVERCELLINACTIVECSSCLASS = "ms-SPLink ms-SpLinkButtonInActive ms-welcomeMenu";
const string HOVERCELLACTIVECSSCLASS = "ms-SPLink ms-SpLinkButtonActive ms-welcomeMenu";
const string ARROWIMAGEURL = "/_layouts/EC.Application/Images/nav_white_arrow.png";

#endregion

#region [Public methods]
#region [Page_Load]

/// <summary>
/// page load event of contact Us Control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
//Check for Page Post back
if (!IsPostBack)
{
//Set Menu Properties
FileActions.MenuControl.Text = MENUTEXT;
//FileActions.MenuControl.CssClass = MENUCSSCLASS;
//FileActions.MenuControl.HoverCellInActiveCssClass = HOVERCELLINACTIVECSSCLASS;
//FileActions.MenuControl.HoverCellActiveCssClass = HOVERCELLACTIVECSSCLASS;
//FileActions.MenuControl.ArrowImageUrl = ARROWIMAGEURL;

//Set XML File Path
string xmlConfigMenuPath = Server.MapPath

("/_layouts/EC.Application/config/FileActions.xml");
// Load the XML File
XElement xeContactUSMenu = XElement.Load(xmlConfigMenuPath);
//Check for XML file Content
if (!string.IsNullOrEmpty(Convert.ToString(xeContactUSMenu)))
{
//Get Specific Node From XML
var menus = from doc in xeContactUSMenu.Descendants(xnContactUsMenu)
select new
{
ID = doc.Attribute(menuID).Value,
MenuText = doc.Attribute(menuText).Value,
MenuDesc = doc.Attribute(menuDesc).Value,
MenuImage = doc.Attribute(menuImage).Value,
MenuURL = SPContext.Current.Web.Url + doc.Attribute(menuURL).Value,
ModalDlgWidth = doc.Attribute(modalWidth).Value,
ModalDlgHeight = doc.Attribute(modalHeight).Value,
};
//Check for Menu Items
if (menus.Count() > 0)
{
//Iterate through the menus to generate Menu Items
foreach (var menuItem in menus)
{
FileActions.AddMenuItem(menuItem.ID,
menuItem.MenuText,
menuItem.MenuImage,
menuItem.MenuDesc,
"",

menuItem.MenuURL);
}
}
}
}
}
#endregion
#endregion

Step 5: verify the following namespaces added in code behind
  • System;
  • System.IO;
  • System.Linq;
  • System.Web.UI;
  • System.Xml;
  • System.Xml.Linq;
  • System.Xml.Xsl;
  • Microsoft.SharePoint;
Step 6: Add following code to register the ascx control on page.
<%@ Register TagPrefix="spfa" TagName="FileAction" src="~/_controltemplates/My.Application/FileActionsMenuControl.ascx" %>

Step 7: Add following code to the page wherever you want to display the menu
<div>
<spfa:FileAction id="fileaction" runat="Server"></spfa:FileAction>
</div>

Step 8: Deploy the control from visual studio and visit the Page on which you have placed the control the Menu should look like below.