Applying Datasources to Sitecore Controls – The Easy Way

Following on from my post The Importance of Datasources I thought I’d show a neat little trick to ensure Datasources are bound to all Sitecore controls within any component/Sublayout that you create.

The approach I normally take to binding Datasources is to firstly inherit from a base class, and get the base class to expose a DataSourceItem property which returns the Datasource, or if one isn’t provided return the context item:

public Item DataSourceItem
{
    get
    {
        // Ensure at the very least Context Item is returned as a fallback
        Item returnItem = Sitecore.Context.Item;

        if (Sublayout != null)
        {
            string dataSourceString = Sublayout.DataSource;

            if (!string.IsNullOrEmpty(dataSourceString))
            {
                Item dbItem = Sitecore.Context.Database.GetItem(dataSourceString);

                if (dbItem != null)
                {
                    returnItem = dbItem;
                }
            }
        }

        return returnItem;
    }
}

(You can get the full base class I use from GitHub at https://github.com/jamielittle/SitecoreToolbox/blob/master/Sitecore.Toolbox/Sublayout/SublayoutBase.cs)

Then in my Component, bind the DatasourceItem to each Sitecore control that is contained within the component:


scTextField1.Item = DatasourceItem;

scTextField2.Item = DatasourceItem;

scImage1.Item = DatasourceItem;

Doing this in every component is a bit of a chore, especially when there are many Sitecore controls contained within the component. So I’ve created a function that will do this for us:


        public void BindDatasourceToSitecoreControls()
        {
            BindDatasourceToSitecoreControls(DataSourceItem);
        }

        public void BindDatasourceToSitecoreControls(Item dataSource)
        {
            if (Controls.Count > 0)
            {
                BindControls(this.Controls, dataSource);
            }
        }

        private void BindControls(ControlCollection controls, Item dataSource)
        {
            foreach (Control control in controls)
            {
                if (control is FieldControl)
                {
                    var fieldControl = control as FieldControl;
                    fieldControl.Item = dataSource;
                }

                if (control is FieldRenderer)
                {
                    var fieldRenderer = control as FieldRenderer;
                    fieldRenderer.Item = dataSource;
                }

                if (control.Controls.Count > 0)
                {
                    BindControls(control.Controls, dataSource);
                }
            }
        }

The BindControls function can be used to recursively traverse through any control collection and when it encounters a control which is of type FieldRenderer or FieldControl (which covers most of the Sitecore controls) it will assign the Datasource that you pass into the function.

There are also two additional functions

  • BindDatasourceToSitecoreContrls() – This function will simply bind the Datasource that is available to any Sitecore controls it finds. This is part of my SublayoutBase.cs base class (as part of the Sitecore Toolbox) and inherits from System.Web.UI.Control so utilises the control collection that is available. You can simply call BindDatasourceToSitecoreControls() from you Page_Load() when inheriting from SubloayoutBase.
  • BingDatasourceToSitecoreControls(Item dataSource) – This function override can be used if a specific Item is used as a Datasource

The above code is included in the SitecoreToolbox on GitHub:

https://github.com/jamielittle/SitecoreToolbox/tree/master/Sitecore.Toolbox

Hopes this helps when using Datasources.

Feel free to leave a comment if you have any questions 🙂

Advertisements

2 thoughts on “Applying Datasources to Sitecore Controls – The Easy Way

  1. Also consider overriding the Render method and putting base.Render inside:

    using (new ContextItemSwitcher(DataSourceItem)) { base.Render(); }

    I forget the exact method signature but hopefully it still makes sense 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s