9 min read

Displaying data in a customized DataGrid

Displaying data is probably the most straightforward task we can ask the DataGrid to do for us. In this recipe, we’ll create a collection of data and hand it over to the DataGrid for display. While the DataGrid may seem to have a rather fixed layout, there are many options available on this control that we can use to customize it.

In this recipe, we’ll focus on getting the data to show up in the DataGrid and customize it to our likings.

Getting ready

In this recipe, we’ll start from an empty Silverlight application. The finished solution for this recipe can be found in the Chapter04/Datagrid_Displaying_Data_Completed folder in the code bundle that is available on the Packt website.

How to do it…

We’ll create a collection of Book objects and display this collection in a DataGrid. However,we want to customize the DataGrid. More specifically, we want to make the DataGridfixed. In other words, we don’t want the user to make any changes to the bound data or move the columns around. Also, we want to change the visual representation of the DataGrid by changing the background color of the rows. We also want the vertical column separators to be hidden and the horizontal ones to get a different color. Finally, we’ll hook into the LoadingRow event, which will give us access to the values that are bound to a row and based on that value, the LoadingRow event will allow us to make changes to the visual appearance of the row.

To create this DataGrid, you’ll need to carry out the following steps:

  1. Start a new Silverlight solution called DatagridDisplayingData in Visual Studio.
    We’ll start by creating the Book class. Add a new class to the Silverlight project in the solution and name this class as Book. Note that this class uses two enumerations—one for the Category and the other for the Language. These can be found in the sample code. The following is the code for the Book class:

    public class Book
    {
    public string Title { get; set; }
    public string Author { get; set; }
    public int PageCount { get; set; }
    public DateTime PurchaseDate { get; set; }
    public Category Category { get; set; }
    public string Publisher { get; set; }
    public Languages Language { get; set; }
    public string ImageName { get; set; }
    public bool AlreadyRead { get; set; }
    }
  2. In the code-behind of the generated MainPage.xaml file, we need to create a generic list of Book instances (List) and load data into this collection.This is shown in the following code:
    private List<Book> bookCollection;
    public MainPage()
    {
    InitializeComponent();
    LoadBooks();
    }
    private void LoadBooks()
    {
    bookCollection = new List<Book>();
    Book b1 = new Book();
    b1.Title = "Book AAA";
    b1.Author = "Author AAA";
    b1.Language = Languages.English;
    b1.PageCount = 350;
    b1.Publisher = "Publisher BBB";
    b1.PurchaseDate = new DateTime(2009, 3, 10);
    b1.ImageName = "AAA.png";
    b1.AlreadyRead = true;
    b1.Category = Category.Computing;
    bookCollection.Add(b1);
    ...
    }
  3. Next, we’ll add a DataGrid to the MainPage.xaml file. For now, we won’t add any extra properties on the DataGrid. It’s advisable to add it to the page by dragging it from the toolbox, so that Visual Studio adds the correct references to the required assemblies in the project, as well as adds the namespace mapping in the XAML code. Remove the AutoGenerateColumns=”False” for now so that we’ll see all the properties of the Book class appear in the DataGrid. The following line of code shows a default DataGrid with its name set to BookDataGrid:
    <sdk:DataGrid x_Name="BookDataGrid"></sdk:DataGrid>
  4. Currently, no data is bound to the DataGrid. To make the DataGrid show the book collection, we set the ItemsSource property from the code-behind in the constructor. This is shown in the following code:
    public MainPage()
    {
    InitializeComponent();
    LoadBooks();
    BookDataGrid.ItemsSource = bookCollection;
    }
  5. Running the code now shows a default DataGrid that generates a column for each public property of the Book type. This happens because the AutoGenerateColumns property is True by default.
  6. Let’s continue by making the DataGrid look the way we want it to look. By default, the DataGrid is user-editable, so we may want to change this feature. Setting the IsReadOnly property to True will make it impossible for a user to edit the data in the control. We can lock the display even further by setting both the CanUserResizeColumns and the CanUserReorderColumns properties to False. This will prohibit the user from resizing and reordering the columns inside the DataGrid, which are enabled by default. This is shown in the following code:
    <sdk:DataGrid x_Name="BookDataGrid"
    AutoGenerateColumns="True"
    CanUserReorderColumns="False"
    CanUserResizeColumns="False"
    IsReadOnly="True">
    </sdk:DataGrid>
  7. The DataGrid also offers quite an impressive list of properties that we can use to change its appearance. By adding the following code, we specify alternating the background colors (the RowBackground and AlternatingRowBackground properties), column widths (the ColumnWidth property), and row heights (the RowHeight property). We also specify how the gridlines should be displayed (the GridLinesVisibility and HorizontalGridLinesBrushs properties). Finally, we specify that we also want a row header to be added (the HeadersVisibility property ).
    <sdk:DataGrid x_Name="BookDataGrid"
    AutoGenerateColumns="True"
    CanUserReorderColumns="False"
    CanUserResizeColumns="False"
    RowBackground="#999999"
    AlternatingRowBackground="#CCCCCC"
    ColumnWidth="90"
    RowHeight="30"
    GridLinesVisibility="Horizontal"
    HeadersVisibility="All"
    HorizontalGridLinesBrush="Blue">
    </sdk:DataGrid>
  8. We can also get a hook into the loading of the rows. For this, the LoadingRow event has to be used. This event is triggered when each row gets loaded. Using this event, we can get access to a row and change its properties based on custom code. In the following code, we are specifying that if the book is a thriller, we want the row to have a red background:
    private void BookDataGrid_LoadingRow(object sender,
    DataGridRowEventArgs e)
    {
    Book loadedBook = e.Row.DataContext as Book;
    if (loadedBook.Category == Category.Thriller)
    {
    e.Row.Background = new SolidColorBrush(Colors.Red);
    //It's a thriller!
    e.Row.Height = 40;
    }
    else
    {
    e.Row.Background = null;
    }
    }

After completing these steps, we have the DataGrid that we wanted. It displays the data (including headers), fixes the columns and makes it impossible for the user to edit the data. Also, the color of the rows and alternating rows is changed, the vertical grid lines are hidden, and a different color is applied to the horizontal grid lines. Using the LoadingRow event, we have checked whether the book being added is of the “Thriller” category, and if so, a red color is applied as the background color for the row. The result can be seen in the following screenshot:

How it works…

The DataGrid allows us to display the data easily, while still offering us many customization options to format the control as needed.

The DataGrid is defined in the System.Windows.Controls namespace, which is located in the System.Windows.Controls.Data assembly. By default, this assembly is not referenced while creating a new Silverlight application. Therefore, the following extra references are added while dragging the control from the toolbox for the first time:

  • System.ComponentModel.DataAnnotations
  • System.Windows.Controls.Data
  • System.Windows.Controls.Data.Input
  • System.Windows.Data

While compiling the application, the corresponding assemblies are added to the XAP file (as can be seen in the following screenshot, which shows the contents of the XAP file). These assemblies need to be added because while installing the Silverlight plugin, they aren’t installed as a part of the CLR. This is done in order to keep the plugin size small. However, when we use them in our application, they are embedded as part of the application. This results in an increase of the download size of the XAP file. In most circumstances, this is not a problem. However, if the file size is an important requirement, then it is essential to keep an eye on this.

Also, Visual Studio will include the following namespace mapping into the XAML file:


From then on, we can use the control as shown in the following line of code:

<sdk:DataGrid x_Name="BookDataGrid"> </sdk:DataGrid>

Once the control is added on the page, we can use it in a data binding scenario. To do so, we can point the ItemsSource property to any IEnumerable implementation. Each row in the DataGrid will correspond to an object in the collection.

When AutoGenerateColumns is set to True (the default), the DataGrid uses a refl ection on the type of objects bound to it. For each public property it encounters, it generates a corresponding column. Out of the box, the DataGrid includes a text column, a checkbox column, and a template column. For all the types that can’t be displayed, it uses the ToString method and a text column.

If we want the DataGrid to feature automatic synchronization, the collection should implement the INotifyCollectionChanged interface. If changes to the objects are to be refl ected in the DataGrid, then the objects in the collection should themselves implement the INotifyPropertyChanged interface.

There’s more

While loading large amounts of data into the DataGrid, the performance will still be very good. This is the result of the DataGrid implementing UI virtualization, which is enabled by default.

Let’s assume that the DataGrid is bound to a collection of 1,000,000 items (whether or not this is useful is another question). Loading all of these items into memory would be a time-consuming task as well as a big performance hit. Due to UI virtualization, the control loads only the rows it’s currently displaying. (It will actually load a few more to improve the scrolling experience.) While scrolling, a small lag appears when the control is loading the new items. Since Silverlight 3, the ListBox also features UI virtualization.

Inserting, updating, and deleting data in a DataGrid

The DataGrid is an outstanding control to use while working with large amounts of data at the same time. Through its Excel-like interface, not only can we easily view the data, but also add new records or update and delete existing ones.

In this recipe, we’ll take a look at how to build a DataGrid that supports all of the above actions on a collection of items.

Getting ready

This recipe builds on the code that was created in the previous recipe. To follow along with this recipe, you can keep using your code or use the starter solution located in the Chapter04/Datagrid_Editing_Data_Starter folder in the code bundle available on the Packt website. The finished solution for this recipe can be found in the Chapter04/Datagrid_Editing_Data_Completed folder.

LEAVE A REPLY

Please enter your comment!
Please enter your name here