Friday, May 8, 2009

Display item type icon in SPGridView after search

I had a request to display, after a search, an icon to make a visual distinction between types of every item matching the criteria. So after creating the query I had to render the SPGridView that I fill with the results.

First was the problem of obtaining the link to the icon describing the type for each search result and after that the display.

For the display part I add a field to grid using TemplateField:

//add type image column for Type
TemplateField typeCol = new TemplateField();
typeCol.HeaderText = “Type”;
typeCol.ItemTemplate = new ItemType("TheId", theList);
grdMain.Columns.Add(typeCol);





Here the grdMain is the SPGridView object and “TheId” is a managed property mapped to ows_ID crawled property. If you use CAML query you have to get the ID of the object into the TheId column.



Now I had to create the class that helped me to display properly the icon. This class inherit ITemplate. In the “InstantiateIn” method we have to write the following:




public void InstantiateIn(Control container)
{
Image img = new Image();
img.DataBinding += new EventHandler(img_DataBinding);
container.Controls.Add(img);
}



As parameters into the constructor of this class we receive the name of the displayed column and the list containing the searched object. Using this data we can get all needed information. Here is the code:




using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;

namespace Com.CFG.WebParts.SearchResultsDocs
{
/// <summary>
/// Implements a custom field which serves as a hyperlink
/// </summary>
class ItemType : ITemplate
{
private String _ColumnDisplay;
private SPList _theList;

#region ITemplate Members

public void InstantiateIn(Control container)
{
Image img = new Image();
img.DataBinding += new EventHandler(img_DataBinding);
container.Controls.Add(img);
}

/// <summary>
/// Initializes the hyperlink field
/// </summary>
/// <param name="ColumnDisplay">The name of the column which contains the value to be displayed</param>
public ItemType(String ColumnDisplay, SPList theList)
{
_ColumnDisplay = ColumnDisplay;
_theList = theList;
}

void img_DataBinding(object sender, EventArgs e)
{
Image img = (Image)sender;

SPGridViewRow container = (SPGridViewRow)img.NamingContainer;

//display name
string itemId = (DataBinder.Eval(container.DataItem, _ColumnDisplay)).ToString();
string imageurl = GetTypeIconLink(_theList, Int32.Parse(itemId));

if (imageurl.Length > 0)
{
img.ImageUrl = "/_layouts/images/" + imageurl;
img.Width = Unit.Pixel(16);
img.Visible = true;
}
else
{
img.Visible = false;
}
}

private string GetTypeIconLink(SPList faqList, int itemId)
{
string returnStr = String.Empty;

SPFile afile = faqList.GetItemById(itemId).File;
if (afile != null)
{
returnStr = afile.IconUrl;
}
return returnStr;
}

#endregion
}
}



If we do not use this class and simply want to add this column to the SPGridView using this code:




SPBoundField acol = new SPBoundField();
acol.HeaderText = "Type";
acol.DataField = "TheId";
acol.Visible = true;
grdMain.Columns.Add(acol);





what we will see into the grid is something like



<img src=”/_layouts/images/…” instead of the icon and this not what we want.



As you noticed from the code, the way to get the path to icon is to use the IconUrl property of item attached file:




private string GetTypeIconLink(SPList faqList, int itemId)
{
string returnStr = String.Empty;

SPFile afile = faqList.GetItemById(itemId).File;
if (afile != null)
{
returnStr = afile.IconUrl;
}
return returnStr;
}



Problem solved.

No comments:

Post a Comment