When displaying custom data through SPGridView you won’t get the same look and feel of the default SharePoint List View. SPMenuField provides a data bound drop-down menu to be used in place of BoundField, TemplateField, or similar controls.
The following describe steps required to add drop-down menu items to a SPGridView control in Web Part.
- Create a Web Part
- Add project references: Microsoft.SharePoint and System.Web
- Add the following namespaces to your class:
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Collections.Generic;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
- Inherits your class with Microsoft.SharePoint.WebPartPages.WebPart
public class SampleGrid : WebPart
{
}
- Override CreateChildControls method, create the ObjectDataSource, SPGridView, SPGridViewPager and SPMenuField controls as shown below:
protected override void CreateChildControls()
{
// Why UseDefaultStyles = false?
// See http://sharepointmalaya.blogspot.com/2009/07/how-to-make-spgridview-to-have-same.html for details
this.UseDefaultStyles = false;
// ObjectDataSource
ObjectDataSource dataSource = new ObjectDataSource();
dataSource.ID = "dataSource";
dataSource.SelectMethod = "SelectData";
dataSource.TypeName = this.GetType().AssemblyQualifiedName;
dataSource.ObjectCreating += new ObjectDataSourceObjectEventHandler(objectCreating);
this.Controls.Add(dataSource);
// SPGridView
spGridView = new SPGridView();
spGridView.ID = "spGridView";
spGridView.DataSourceID = dataSource.ID;
spGridView.AutoGenerateColumns = false;
spGridView.AllowPaging = true;
spGridView.PageSize = 10;
spGridView.AllowSorting = true;
spGridView.EmptyDataText = string.Empty;
this.Controls.Add(spGridView);
// SPGridViewPager
pager = new SPGridViewPager();
pager.GridViewId = spGridView.ID;
this.Controls.Add(pager);
// SPMenuField - Name field
SPMenuField nameCol1 = new SPMenuField();
nameCol1.HeaderText = "Name";
nameCol1.TextFields = "Name";
nameCol1.NavigateUrlFields = "Name,Email,WebSite";
nameCol1.NavigateUrlFormat = "/_layouts/sharepointmalaya/DispDetails.aspx?WebPartID=" + this.ID + "&FilterName={0}&ReturnUrl=" + Page.Request.Url.ToString();
nameCol1.TokenNameAndValueFields = "KEYNAME=Name,KEYEMAIL=Email,KEYWEBSITE=WebSite";
nameCol1.SortExpression = "Name";
nameCol1.MenuTemplateId = "menuTemplate";
// MenuTemplate
MenuTemplate menuTemplate = new MenuTemplate();
menuTemplate.ID = "menuTemplate";
this.Controls.Add(menuTemplate);
spGridView.Columns.Add(nameCol1);
// MenuTemplate - View Item
MenuItemTemplate menuItemTemplate0 = new MenuItemTemplate("View Item", "~/_layouts/images/LIST.GIF");
menuItemTemplate0.ClientOnClickNavigateUrl = "/_layouts/sharepointmalaya/DispDetails.aspx?WebPartID=" + this.ID + "&FilterName={%KEYNAME%}&ReturnUrl=" + Page.Request.Url.ToString();
menuTemplate.Controls.Add(menuItemTemplate0);
// MenuTemplate - Seperator
MenuSeparatorTemplate menuSepTemplate = new MenuSeparatorTemplate();
menuTemplate.Controls.Add(menuSepTemplate);
// MenuTemplate - Open WebSite
MenuItemTemplate menuItemTemplate1 = new MenuItemTemplate("Open WebSite", "~/_layouts/images/ASP16.GIF");
menuItemTemplate1.ClientOnClickNavigateUrl = "javascript:window.open('%KEYWEBSITE%');";
menuTemplate.Controls.Add(menuItemTemplate1);
// MenuTemplate - Send Email
MenuItemTemplate menuItemTemplate2 = new MenuItemTemplate("Send Email", "~/_layouts/images/EML16.GIF");
menuItemTemplate2.ClientOnClickScript = "javascript:document.location.href='MailTo:%KEYEMAIL%;'";
menuTemplate.Controls.Add(menuItemTemplate2);
// BoundField - Email field
BoundField nameCol2 = new BoundField();
nameCol2.DataField = "Email";
nameCol2.SortExpression = "Email";
nameCol2.HeaderText = "Email";
spGridView.Columns.Add(nameCol2);
// BoundField - WebSite field
BoundField nameCol3 = new BoundField();
nameCol3.DataField = "WebSite";
nameCol3.SortExpression = "WebSite";
nameCol3.HeaderText = "WebSite";
spGridView.Columns.Add(nameCol3);
this.ChildControlsCreated = true;
}
- Code above create three (3) drop-down menu items and a separator menu as shown below:
- Clicking on the “View Item” redirects to custom page in the _layouts folder. When clicking on the “Open WebSite”, it opens web site and “Send Email” menu open client email form.
- Please note SPMenuField has a property TokenNameAndValueFields which can be used to store token names and values in the following format:
SPMenuField.TokenNameAndValueFields = "KEYNAME=Name,KEYEMAIL=Email,KEYWEBSITE=WebSite";
- To consume SPMenuField token values, you must specify token name within the % sign as shown below:
“%TOKEN_NAME%” OR “%KEYWEBSITE%”
- As shown in code example above, ObjectDataSource control require “SelectData” method. You need to create a public method SelectData which returns a System.Data.DataTable – a dummy data which has three (3) columns which are “Name”, “Email” and “WebSite”. See below:
public DataTable SelectData()
{
DataTable table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("Email");
table.Columns.Add("WebSite");
table.Rows.Add("SharePoint Malaya","sharepointmalaya@gmail.com","http://sharepointmalaya.blogspot.com");
table.Rows.Add("Faris","faris@gmail.com","http://sharepointmalaya.blogspot.com");
table.Rows.Add("Farhana","farhana@gmail.com","http://sharepointmalaya.blogspot.com");
return table;
}
- In addition, ObjectDataSource control implement event handler ObjectCreating – You also need to create instance containing the event data as shown below:
private void objectCreating(object sender, ObjectDataSourceEventArgs e)
{
e.ObjectInstance = this;
}
- Next, bind the data with the SPGridView control as shown below:
protected override void Render(HtmlTextWriter writer)
{
if (ChildControlsCreated)
spGridView.DataBind();
base.Render(writer);
}
- Build and deploy to SharePoint site. That’s it – All Done. See below for screenshot:
Get sample code here:
2 comments:
Nice - I like it (Y)
I'm following this excellent article on how to take advantage of these classes. Got working most of what I need, but hit a snag.
I'm adding menus to my items. The tokens are resolving OK, except that in one of my urls I have a repeated token. Like this:
targetColumn.TokenNameAndValueFields = "HOSTURL=HostUrl,DOCID=DocumentId,LISTID=ListId";
ModerateMenuItem.ClientOnClickNavigateUrl= %HOSTURL%/_layouts/... (a bunch of stuff) ... &ListId={%LISTID%}&Source=%HOSTURL%&IsDlg=1
The first %HOSTURL% is matched to the property on the data source, but the second is not. It renders as %HOSTURL%
I tried adding a second HOSTURL entry on TokenNameAndValueFields I get an exception:
System.ArgumentException - mscorlib
Message: An item with the same key has already been added.
Tried with another token name, say HOSTURL2=HostUrl. Same exception
Any ideas?
Post a Comment