One of my latest challenges was to display one of the new SharePoint 2010 social fields in a datagrid. At first this was just to display the field, but after the client seen the mouse-over functionality on the list item, they wanted to be able to assign a rating straight from the grid without having to go to the item itself. So, here’s how I went about it.
Firstly I created a custom control call as seen in the code sample below:
- [DefaultProperty("Rating")]
- [ToolboxData("<{0}:RatingControl runat=server></{0}:RatingControl>")]
- public class RatingControl : WebControl
- {
- protected override void OnInit(EventArgs e)
- {
- base.OnInit(e);
- Page.RegisterRequiresControlState(this);
- }
- [Bindable(true)]
- [Category("Binding")]
- [DefaultValue("")]
- [Localizable(true)]
- public SPField RatingField
- {
- get
- {
- SPField field = (SPField)ViewState["RatingField"];
- return field;
- }
- set
- {
- ViewState["RatingField"] = value;
- }
- }
- [Bindable(true)]
- [Category("Binding")]
- [DefaultValue("")]
- [Localizable(true)]
- public int ListItemId
- {
- get
- {
- return Convert.ToInt32(ViewState["ListItemId"]);
- }
- set
- {
- ViewState["ListItemId"] = value;
- }
- }
- [Bindable(true)]
- [Category("Binding")]
- [DefaultValue("")]
- [Localizable(true)]
- public Guid ListId
- {
- get
- {
- Guid id = (Guid)ViewState["ListId"];
- return id;
- }
- set
- {
- ViewState["ListId"] = value;
- }
- }
- protected override void CreateChildControls()
- {
- if (this.ChildControlsCreated)
- return;
- BaseFieldControl renderingcontrol = this.RatingField.FieldRenderingControl;
- renderingcontrol.ControlMode = SPControlMode.Display;
- renderingcontrol.ListId = this.ListId;
- renderingcontrol.ItemId = this.ListItemId;
- Controls.Add(renderingcontrol);
- this.ChildControlsCreated = true;
- }
Next, after adding a new template column to the datagrid containing a place holder (DataGrid source), then binding the data source to the ListItemCollection returned.
- <asp:TemplateColumn>
- <HeaderTemplate>
- Rating
- </HeaderTemplate>
- <ItemTemplate>
- <asp:PlaceHolder runat="server" ID="RatingPlaceHolder"></asp:PlaceHolder>
- </ItemTemplate>
- </asp:TemplateColumn>
I create a new instance of the rating control on the girdview OnItemDataBound event receiver and add it to the place holder.
- protected void SearchResultsGridView_OnItemDataBound(object sender, DataGridItemEventArgs e)
- {
- if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
- {
- Label lastModifiedLabel = (Label)e.Item.FindControl("LastModifiedLabel");
- lastModifiedLabel.Text = Convert.ToDateTime(DataBinder.Eval(e.Item.DataItem, "ModifiedDate")).ToString("dd-MMM-yyyy");
- PlaceHolder placeHolder = (PlaceHolder)e.Item.FindControl("RatingPlaceHolder");
- ratingControl = new RatingControl();
- ratingControl.RatingField = (SPField)DataBinder.Eval(e.Item.DataItem, "RatingField");
- ratingControl.ListId = (Guid)DataBinder.Eval(e.Item.DataItem, "ListId");
- ratingControl.ListItemId = Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, "Id"));
- placeHolder.Controls.Add(ratingControl);
- }
- }
Job Done!
