I'm currently working on my first SharePoint web part to aggregate information from numerous announcement lists in various sites and allow them to be displayed in one single web part.
I've used two guides but had little success, these are Powlo's blog and Erik Burgers SPGridView series, I have had more success with Eriks than Powlos guide, but it is still not working as intended.
When attempting to sort I click on the title of the column I wish to sort and this error is displayed within the webpage. The drop down is then shown giving the option to sort by asscending and descending, once I click on one of the options I recieve a full page error saying "The Gridview 'grid' first event sorting which wasn't handled.
Second to this I have paging implemented but when I try to use it the web part displays the message "There are no items to show in this view".
Further to that, when using the drop down for Sorting no filtering options appear.
I've included my code below, so if you have any suggestions let me know please.
(Excuse the messy code I've been using it for debugging and generally playing with things to see if they would make it work.)
public partial class AggregationWebPartUserControl : UserControl
{
SPSite thisSite = SPContext.Current.Site;
SPWebCollection thisWeb;
SPListCollection siteLists;
DataTable dt;
ObjectDataSource gridDS;
protected void Page_Load(object sender, EventArgs e)
{
grid.AutoGenerateColumns = false;
thisWeb = thisSite.AllWebs; //thisSite.OpenWeb();
if (!Page.IsPostBack)
{
BindToGrid(thisWeb, grid);
}
}
private void BindToGrid(SPWebCollection thisWeb, SPGridView grid)
{
//Use a ObjectDataSource to bind to the data table
gridDS = new ObjectDataSource();
gridDS.ID = "gridDS";
//We select the method the data is pulled from
gridDS.SelectMethod = "SelectData";
gridDS.TypeName = this.GetType().AssemblyQualifiedName;
gridDS.ObjectCreating += new ObjectDataSourceObjectEventHandler(gridDS_ObjectCreating);
this.Controls.Add(gridDS);
//Set the datasource of the grid to the instance of ObjectDataSource
grid.DataSourceID = gridDS.ID;
grid.AutoGenerateColumns = false;
//Turns on Paging along with setting the default page size
grid.AllowPaging = true;
grid.PageSize = 10;
//Allows sorting
grid.AllowSorting = true;
//Filtering
grid.AllowFiltering = true;
//Allows filtering on the Created and ListName columns
grid.FilterDataFields = ",,ListName";
grid.FilteredDataSourcePropertyName = "FilterExpression";
grid.FilteredDataSourcePropertyFormat = "{1} = '{0}'";
//FIltering and Sorting Event handlers
grid.RowDataBound += new GridViewRowEventHandler(grid_RowDataBound);
gridDS.Filtering += new ObjectDataSourceFilteringEventHandler(gridDS_Filtering);
grid.Sorting += new GridViewSortEventHandler(grid_Sorting);
this.Controls.Add(grid);
//Sets up the paging used on the page
SPGridViewPager pager = new SPGridViewPager();
pager.ID = "newPager";
pager.GridViewId = grid.ID;
this.Controls.Add(pager);
}
protected sealed override void Render(HtmlTextWriter writer)
{
GenerateColumns();
grid.DataBind();
base.Render(writer);
}
private void GenerateColumns()
{
BoundField column = new BoundField();
column.DataField = "Title";
column.SortExpression = "Title";
column.HeaderText = "Title";
grid.Columns.Add(column);
column = new BoundField();
column.DataField = "Created";
column.SortExpression = "Created";
column.HeaderText = "Created";
grid.Columns.Add(column);
column = new BoundField();
column.DataField = "ListName";
column.SortExpression = "ListName";
column.HeaderText = "ListName";
grid.Columns.Add(column);
}
public DataTable SelectData()
{
try
{
dt = new DataTable();
dt.Columns.Add("Title");
dt.Columns.Add("Created");
dt.Columns.Add("ListName");
DataRow row;
foreach (SPWeb web in thisWeb)
{
siteLists = web.Lists;
siteLists.ListsForCurrentUser = true;
foreach (SPList list in siteLists)
{
if (list.BaseTemplate.ToString() == "Announcements")
{
SPListItemCollection listItem = list.Items;
foreach (SPListItem item in listItem)
{
row = dt.Rows.Add();
row["Title"] = item["Title"].ToString();
//row["Title"] = "<a href=\"" + item.Url + "\">" + item["Title"].ToString() + "</a>";
row["Created"] = item["Created"].ToString();
row["ListName"] = list.Title;
//row["ListName"] = "<a href=\"" + list.DefaultViewUrl + "\">" + list.Title + "</a>";
}
}
}
}
return dt;
}
catch (Exception s)
{
return dt;
}
}
#region eventhandlers
private void grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (sender == null || e.Row.RowType != DataControlRowType.Header)
{
return;
}
SPGridView grid = sender as SPGridView;
if (String.IsNullOrEmpty(grid.FilterFieldName))
{
return;
}
// Show icon on filtered column
for (int i = 0; i < grid.Columns.Count; i++)
{
DataControlField field = grid.Columns[i];
if (field.SortExpression == grid.FilterFieldName)
{
Image filterIcon = new Image();
filterIcon.ImageUrl = "/_layouts/images/filter.gif";
filterIcon.Style[HtmlTextWriterStyle.MarginLeft] = "2px";
// If we simply add the image to the header cell it will
// be placed in front of the title, which is not how it
// looks in standard SharePoint. We fix this by the code
// below.
Literal headerText = new Literal();
headerText.Text = field.HeaderText;
PlaceHolder panel = new PlaceHolder();
panel.Controls.Add(headerText);
panel.Controls.Add(filterIcon);
e.Row.Cells[i].Controls[0].Controls.Add(panel);
break;
}
}
}
//Used to filter data
private void gridDS_Filtering(object sender, ObjectDataSourceFilteringEventArgs e)
{
ViewState["FilterExpression"] = ((ObjectDataSourceView)sender).FilterExpression;
}
//Used to sort the data
private void grid_Sorting(object sender, GridViewSortEventArgs e)
{
if (ViewState["FilterExpression"] != null)
{
gridDS.FilterExpression = (string)ViewState["FilterExpression"];
}
}
protected sealed override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
if (Context.Request.Form["__EVENTARGUMENT"] != null &&
Context.Request.Form["__EVENTARGUMENT"].EndsWith("__ClearFilter__"))
{
// Clear FilterExpression
ViewState.Remove("FilterExpression");
}
}
private void gridDS_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
e.ObjectInstance = this;
}
#endregion
}