LibrarySites.Banner

Customizing With Large Data Sets

A popular and easy-to-use control for displaying a list of content is the Listview.  When dealing with 5, 10 or 20 rows of information, the Listview control usually works well.  But in cases where hundreds (or more) rows need to be handled, something more powerful is needed.  Sitecore uses the ComponentArt Grid control.  This post covers how to use this control so you can display large amounts of information in a way that is consistent with the Sitecore client.

What is wrong with the Listview control?

One reason the Listview control is popular is that one of the Sheer UI articles on SDN describes how to use it.  There are cases where the Listview is appropriate, but the control has some significant limitations when it comes to scalability.

All of the content that appears in the Listview is loaded when the Listview is rendered.  This means that if you have 1000 records to display, information for all 1000 records must be loaded at once.  Similarly, all of the content appears when the Listview is rendered.  Using the 1000 records example, this means you must display all 1000 records as 1000 rows. 

The ComponentArt Grid control is a better option for this example.  It allows information to be retrieved when needed, so instead of retrieving all 1000 records, the Grid control can retrieve the first 10 records, and then, if the user wants to retrieve the next 10, the Grid control can handle sending the command to retrieve the next 10 records.  So it supports pagination.  It also supports searching and grouping, which can be very helpful when working with large data sets.

A word about the quantity of code

There's no hiding this: a lot of code is needed to use the Grid control.  This is a very complex control, with a lot of uses and options. 

The good news is that you really don't need to worry about most of the code.  If you are satisfied with the functionality that is available on screens like "User Manager" and "My Items", then you only need to consider which columns you want to display and where the data that appears in the Grid comes from.

role-manager

The Role Manager application uses the Grid control.

Getting started

In order to demonstrate the Grid control, I am going to create a custom application.

  1. The first step is to define the user interface.  I will do this using a XAML file (but this is just one of many ways custom user interfaces can be defined in Sitecore).  Create the following file:
    * [sitecore install dir]\Website\sitecore modules\Shell\Grid Example\Grid Example.xaml.xml
  2. As I mentioned earlier, there is quite a bit of code to include in this file.  The source is available here.  There are a few sections in this file that you may want to customize:
    * Lines 84-89: grid columns are specified
    * Line 111: the message that is displayed when the paging slider is moved
  3. The XAML file (line 4) specifies the name of the code-behind class.  Using Visual Studio, create the following class:
    * Assembly: GridExample
    * Namespace: GridExample
    * Class name: GridExamplePage
  4. Use the following code for the class.  Notice line 23.  This is where the data source for the grid is specified:

        1 using System;

        2 using Sitecore.Controls;

        3 using ComponentArt.Web.UI;

        4 using Sitecore.Diagnostics;

        5 using Sitecore.Web.UI.XamlSharp.Xaml;

        6 using Sitecore.Data.Items;

        7 using Sitecore.Data;

        8 using Sitecore.Web.UI.Grids;

        9 

       10 namespace GridExample

       11 {

       12     public class GridExamplePage : ModalDialogPage

       13     {

       14         protected Grid ItemsGrid;

       15         protected override void OnLoad(EventArgs e)

       16         {

       17             Assert.ArgumentNotNull(e, "e");

       18             base.OnLoad(e);

       19             if (!XamlControl.AjaxScriptManager.IsEvent)

       20             {

       21                 ID id = new ID(Sitecore.Context.Request.QueryString["id"]);

       22                 Item item = Sitecore.Context.Database.GetItem(id);

       23                 GridSource<Item> source = new GridSource<Item>(item.GetChildren());

       24                 ComponentArtGridHandler<Item>.Manage(this.ItemsGrid, source, true);

       25             }

       26         }

       27     }

       28 } 


  5. A command class is needed to display the GridExamplePage.  Create the following class:
    * Assembly: GridExample
    * Namespace: GridExample
    * Class name: ShowGridExamplePageCommand
  6. Use the following code for the class:

        1 using System;

        2 using Sitecore.Shell.Framework.Commands;

        3 using Sitecore.Diagnostics;

        4 using Sitecore.Web.UI.Sheer;

        5 using Sitecore.Text;

        6 using System.Collections.Specialized;

        7 

        8 namespace GridExample

        9 {

       10     public class ShowGridExamplePageCommand:Command

       11     {

       12         public override void Execute(CommandContext context)

       13         {

       14             Assert.ArgumentNotNull(context, "context");

       15             UrlString url = new UrlString("/sitecore/shell/~/xaml/GridExample.GridExamplePage.aspx");

       16             url["id"] = context.Items[0].ID.ToString();

       17             SheerResponse.ShowModalDialog(url.ToString(), "650", "500");

       18         }

       19     }

       20 } 


  7. Compile and deploy the assembly so it is available to Sitecore.
  8. A config file is needed.  Create the following file:
    * [sitecore install dir]\Website\App_Config\Include\GridExample.config
  9. Use the following code for the file:

        1 <?xml version="1.0" encoding="utf-8" ?>

        2 <configuration xmlns:patch="https://www.sitecore.com/xmlconfig/">

        3     <sitecore>

        4         <controlSources>

        5             <source mode="on" namespace="Sitecore.Web.UI.XmlControls" folder="/sitecore modules/Shell/Grid Example" deep="false"/>

        6         </controlSources>

        7         <commands>

        8             <command name="gridexample:show" type="GridExample.ShowGridExamplePageCommand, GridExample"/>

        9         </commands>

       10     </sitecore>

       11 </configuration>


  10. Next I need to create a button in the Sitecore client that will open the custom page.  My previous post includes step-by-step instructions (see the "Create custom button" section).  Use the following values:
    * Name: Grid Example
    * Header: Grid Example
    * Icon: Business/24x24/table_selection_block.png
    * Click: gridexample:show
    * Tooltip: Show the grid example page
  11. If you click the button you should see a dialog that displays the children of the item selected in the Content Editor.

    grid example 1

Handling grid events

The grid control responds to server-side and client-side events.  Server-side events involve changing the information that's being displayed.  For example, when the sort order is changed or a filter is applied, a server-side event is triggered.  Client-side events involve a a user doing something via the user interface.  For example, when the user selects a row or double-clicks a row.

Handling server-side events is done the same way as any other control.  More important, however, is the fact that server-side events are handled for the most part by the "ComponentArtGridHandler" class.  Since my goal is to be able to display a large number of records, there is no reason for me to handle server-side events.

Client-side events are another matter.  Handling client-side events is important because this allows a screen to do more than just display information.  For example, a client-side event is triggered when a user selects a row.  By handling that client-side event, it becomes possible for the user to select rows and then instruct Sitecore to perform a task using the selected rows in some way.

In this example, I am going to display information about the selected row when the user double-clicks the row.

  1. The first thing that is needed is a Javascript function which will trigger a Sitecore command.  Add the following code to the XAML file.  It should go above the line that declares the "AjaxScriptManager":

        1 <Script runat="server">

        2     function ItemsGrid_onDoubleClick(sender, eventArgs) {

        3         scForm.postRequest("", "", "", "gridexample:doubleclick");

        4     }

        5 </Script>


  2. Next I need this function to run when a row in the grid is double-clicked.  Add the following code to the "OnLoad" method in the "GridExamplePage" class.  The code should be added into the same if-block where the GridSource is assigned:

        this.ItemsGrid.ClientEvents.ItemDoubleClick = new ClientEvent("ItemsGrid_onDoubleClick");


  3. The "GridExamplePage" class must also implement the "IHasCommandContext" interface.  This interface enables Sitecore to pass information to the "gridexample:doubleclick" command.  This interface defines a single method, which I implement using the following code:

        1 public CommandContext GetCommandContext()

        2 {

        3     string[] ids = GridUtil.GetSelectedValue("ItemsGrid").Split('|');

        4     List<Item> items = new List<Item>();

        5     foreach (string id in ids)

        6     {

        7         Item item = Sitecore.Context.Database.GetItem(new ID(id));

        8         items.Add(item);

        9     }

       10     CommandContext context = new CommandContext(items.ToArray());

       11     return context;

       12 } 


  4. The command that runs when the row is double-clicked must be implemented.  Create the following class:
    * Assembly: GridExample
    * Namespace: GridExample
    * Class name: DoubleClickExample
  5. Use the following code for the class:

        1 using System;

        2 using System.Text;

        3 using Sitecore.Data.Items;

        4 using Sitecore.Web.UI.Sheer;

        5 using System.Collections.Generic;

        6 using Sitecore.Shell.Framework.Commands;

        7 

        8 namespace GridExample

        9 {

       10     public class DoubleClickCommand : Command

       11     {

       12         public override void Execute(CommandContext context)

       13         {

       14             StringBuilder builder = new StringBuilder();

       15             builder.AppendFormat("{0} items were selected in the grid:\n\n", context.Items.Length);

       16             foreach (Item item in context.Items)

       17             {

       18                 builder.AppendFormat("{0}\n", item.Name);

       19             }

       20             SheerResponse.Alert(builder.ToString(), new string[0]);

       21         }

       22     }

       23 } 


  6. Compile and deploy the assembly so it is available to Sitecore.
  7. The Javascript function sends the "gridexample:doubleclick" command.  This command needs to be mapped to the "DoubleClickCommand" class.  Add the following code to the config file:

        <command name="gridexample:doubleclick" type="GridExample.DoubleClickCommand, GridExample"/>


  8. Now, when I double-click on a row in the grid, a popup appears with some information about the selected item.

    grid example popup 1

Conclusion 

Using the grid control is a little more involved than using the Listview, but a lot more functionality is available with the grid.  When dealing with large data sets, the grid's paging, sorting and filtering features become very useful.  Hopefully this post will help you get started using the grid control in your customizations.

  • Hi Sitecore Team,   I'm using Sitecore v6.3 and trying to create role based menu.But It's not working. Suppose that I have created 5 pages and 5 menu items are showing.  Now I want to create one user who does have access only for 4 pages then once he/she logins should see only 4 menu items not 5.   Could you please let me know ? If it is possible in sitecore feature.Or how to achieve it.  Regards Nitish

  • i am getting error Xaml Control "GridExample.GridExamplePage" not found

  • Hi Adam,  I've created a button and I was trying to fill grid in button click method, not in OnLoad as you show in sample. Grid remains unfilled with result, even I call XamlControl.AjaxScriptManager.SetOuterHtml(), ev. SheerResponse.SetOuterHtml(). What to call to instruct Grid to invalidate and show binded datas on client?

  • the source code is not avaliable anymore