Tuesday 13 September 2011

BaseFieldControl class , How to render a field on a form page (not a list view page) by using child controls in a Web Part

The BaseFieldControl is a class that renders a field on a form page (not a list view page) by using one or more child controls such as a label, link, or text box control.

This class has to be used as a base class for deriving controls to render specific types of fields on lists forms (but not on list views). Objects of the BaseFieldControl type are primarily used as the value of the SPField.FieldRenderingControl property.

In few words, this is probably the fastest way to work with the user interface and web parts. It is much faster than the native Web UI.

Work with the BaseFieldControl class is not easy and to be honest it is really tedious but the end result and the performance in your webparts will be astonishing.

This is how it works, it gets the data and of your child controls and embedded it into the class. This class doesn’t care about the field type, so when you just need to pass it as a SPField and  render it.

I am going to build a Step by Step so we know how this works. This example will display the Items of “Shared Documents” list, and it will only display the fields you can see in the default view. In order to make the things easier for for I have built two methods:

  • DisplayFieldsSimpleMode(): This method retrieve the fields of the list in a single line. It is an easy approach so you know how it works.
  • DisplayFieldsInATable():This method retrieve the fields of the list in a table. It is a complex approach so you know what you can do.

1- Go To Visual Studio 2010->New Project-> Sharepoint –> 2010 –> Empty Sharepoint Project. Call it netsourcecodeBaseFieldControl, click OK. Now Select Deploy As Farm Solution and click on Finish

2- Right Click on the Project->Add->New Item…->WebPart call it BaseFieldControlWebpart and click OK.

3- Go to features and rename Feature1 to BFCFeature. Your project should look like this now:

image

4- Go to BaseFieldControlWebpart.cs , remove all the stuff you got inside, and copy this code:

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace netsourcecodeBaseFieldControl.BaseFieldControlWebpart
{
    [ToolboxItemAttribute(false)]
    public class BaseFieldControlWebpart : WebPart
    {
        private SPList _lSharedDocumentsList;
        private void GetListInstance()
        {
            // The web used
            using (SPWeb web = SPContext.Current.Web)
            {
                // This is the code you could have easily guessed :
                _lSharedDocumentsList = web.Lists["Shared Documents"];
            }
        }
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            DisplayFieldsSimpleMode();
            DisplayFieldsInATable();
        }
        private void DisplayFieldsSimpleMode()
        {
            SPField _spField = null;
            BaseFieldControl _bBaseFieldControlField = null;
             using (SPSite site = new SPSite(SPContext.Current.Site.ID))
                    {
                        using (SPWeb web = site.OpenWeb())
                        {
                            // This is the code you could have easily guessed :
                            _lSharedDocumentsList = web.Lists["Shared Documents"];
                            foreach (SPListItem _splListItem in this._lSharedDocumentsList.Items)
                            {
                                //## THIS FOR EACH WILL GO TROUGHT ALL THE FIELDS
                                //## YOU CAN SEE IN YOUR DEFAULT VIEW
                                foreach (string _sFieldName in this._lSharedDocumentsList.DefaultView.ViewFields)
                                {                                   
                                    //## GET THE SPField INSTANCE
                                    //## NOTE THAT IS GETTING THE SPField FROM THE SPListItem FIELDS
                                    _spField = _splListItem.Fields.GetField(_sFieldName);
                                    //## WE BUILD THE BaseFieldControl CLASS
                                    _bBaseFieldControlField = _spField.FieldRenderingControl;
                                    _bBaseFieldControlField.ID = Guid.NewGuid().ToString();
                                    _bBaseFieldControlField.FieldName = _spField.InternalName;
                                    _bBaseFieldControlField.ListId = this._lSharedDocumentsList.ID;
                                    _bBaseFieldControlField.ItemId = _splListItem.ID;
                                    _bBaseFieldControlField.ControlMode = SPControlMode.Display;
                                    //## FILLING THE BaseFieldControl CLASS                                    
                                    SPContext Context = SPContext.GetContext(HttpContext.Current, _splListItem.ID, this._lSharedDocumentsList.ID, web);
                                    _bBaseFieldControlField.ItemContext = Context;
                                    _bBaseFieldControlField.RenderContext = Context;
                                    //## ADDING THE BaseFieldControlField
                                    Controls.Add(_bBaseFieldControlField);
                                }
                            }                    
                }
            }
        }
        private void DisplayFieldsInATable()
        {
            //## TABLE VARIABLES
            HtmlTable _hTable = new HtmlTable();
            HtmlTableRow _hRow = null;
            HtmlTableCell _hCellForName = null;
            HtmlTableCell _hCellForValue = null;
            //## LIST VARIABLES
            SPField _spField = null;
            BaseFieldControl _bBaseFieldControlField = null;
            LiteralControl _lLiteralControlValue = null;
            //## FILLING THE BaseFieldControl CLASS
            using (SPSite site = new SPSite(SPContext.Current.Site.ID))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    // This is the code you could have easily guessed :
                    _lSharedDocumentsList = web.Lists["Shared Documents"];
                    foreach (SPListItem _splListItem in this._lSharedDocumentsList.Items)
                    {
                        //## THIS FOR EACH WILL GO TROUGHT ALL THE FIELDS
                        //## YOU CAN SEE IN YOUR DEFAULT VIEW
                        foreach (string _sFieldName in this._lSharedDocumentsList.DefaultView.ViewFields)
                        {
                            // Makle a new row
                            _hRow = new HtmlTableRow();
                            //## GET THE SPField INSTANCE
                            //## NOTE THAT IS GETTING THE SPField FROM THE SPListItem FIELDS
                            _spField = _splListItem.Fields.GetField(_sFieldName);
                            //## CREATES A CELL FOR THE NAME AND INSERTS THE TITLE
                            _hCellForName = new HtmlTableCell();
                            _hCellForName.InnerHtml = string.Format("{0}:&nbsp&nbsp", _spField.Title);
                            //## ADDING THE CELL INTO OUR ROW
                            _hRow.Cells.Add(_hCellForName);
                            //## CREATES A CELL FOR THE VALUE AND INSERTS THE
                            //## VALUE FROM OUR BaseFieldControl CLASS
                            //############## STARTS HERE #####################
                            _hCellForValue = new HtmlTableCell();
                            //## WE BUILD THE BaseFieldControl CLASS
                            _bBaseFieldControlField = _spField.FieldRenderingControl;
                            _bBaseFieldControlField.ID = Guid.NewGuid().ToString();
                            _bBaseFieldControlField.FieldName = _spField.InternalName;
                            _bBaseFieldControlField.ListId = this._lSharedDocumentsList.ID;
                            _bBaseFieldControlField.ItemId = _splListItem.ID;
                            _bBaseFieldControlField.ControlMode = SPControlMode.Display;                    
                            SPContext Context = SPContext.GetContext(HttpContext.Current, _splListItem.ID, this._lSharedDocumentsList.ID, web);
                            _bBaseFieldControlField.ItemContext = Context;
                            _bBaseFieldControlField.RenderContext = Context;
                            _lLiteralControlValue = new LiteralControl(_bBaseFieldControlField.GetDesignTimeHtml());
                    
                            //## ADDING THE CELL INTO OUR ROW
                            _hRow.Cells.Add(_hCellForValue);
                            // Add the row to the table
                            _hTable.Rows.Add(_hRow);
                            _hCellForValue.Controls.Add(_lLiteralControlValue);
                        }
                    }
                }
            }
            //## Adding the table
            Controls.Add(_hTable);          
        }
    }
}

5- Build and Deploy the solution, this is the end result after adding your web part:


image


Download the project here:


image

No comments: