Creating a Data-Bound application using Infragistics xamGrid Control

Posted by: Mahesh Sabnis , on 6/11/2012, in Category Product Articles
Views: 53258
Abstract: In this article, we will explore the Infragistics xamGrid Control to create LOB apps using Silverlight

I was recently given the opportunity to do some hands-on the Infragistics NetAdvantage for Silverlight Suite for creating LOB applications. The Metro UI ready touch friendly controls provided in this toolset have been engineered to enhance productivity, deliver rich advanced data visualizations and leverage the sophisticated capabilities of Silverlight. The toolset is enriched with controls like xamGrid, Barcodes, Charts, Maps and many more for building compelling Line-of-Business (LOB) applications using Silverlight, with less customizations. For someone like me who has used the plain vanilla Silverlight DataGrid control and has written a lot of custom code for providing Excel features like filteration, Pagination, New Row Addition, Grouping, etc, this toolset made me feel as elevated as a kid in a candy shop. 

In my opinion, the best way to explore a toolkit is to visualize your data in it and what better control to do this than the grid itself. In this article, we will explore how to use one of the popular Infragistics control, the XamGrid for developing a Data-bound application using Silverlight. So let’s get started.

For this article, I am using VS 2011 Beta (VS 2012 RC has been released) and Silverlight 5.0 as the Infragistics toolset is now supporting Silverlight 5.0. In the article, I have touched upon the following features while exploring the XamGrid:

  • Pagination
  • Column Data Binding
  • Editing and Deleting Features with Command
  • Sorting columns and preventing sorting on some Columns
  • Excel like Filtration
  • Exporting Data in XamGrid to Word Document

Pre-Requisites:

Step 1: Open VS 2012 and create new blank solution, name it as ‘SL5_Xam_Grid_Programming. To this solution, add a new WCF Service Application project, name it as ‘WCF_DataService’. For this application, I am using the ADO.NET Entity Framework for the ‘EmployeeInfo’ table as shown below :

I1_TB_Design

I have added this table under the Sql Server ‘Company’ database. In the WCF Service, add a new ADO.NET Entity Data Model and complete the Wizard by using the above table.

Step 2: Rename ‘IService1.cs’ to IService.cs and Service1.svc to Service.svc. Add the following OperationContracts in the ‘IService.cs’:

[ServiceContract]
public interface IService
{
    [OperationContract]
    EmployeeInfo[] GetEmployees();
    [OperationContract]
    EmployeeInfo GetEmployeeByEmpNo(int EmpNo);
    [OperationContract]
    void CreateEmployee(EmployeeInfo objEmp);
    [OperationContract]
    void UpdateEmployee(EmployeeInfo objEmp);
    [OperationContract]
    void DeleteEmployee(int EmpNo);
}

Add the following code in Service class:

public class Service : IService
{
    CompanyEntities objContext;
    public Service()
    {
        objContext = new CompanyEntities();
    }
    public EmployeeInfo[] GetEmployees()
    {
        var Employees = objContext.EmployeeInfoes.ToArray();
        return Employees;
    }

    public EmployeeInfo GetEmployeeByEmpNo(int EmpNo)
    {
        var Employee = objContext.EmployeeInfoes.First(e => e.EmpNo == EmpNo);
        return Employee;
    }

    public void CreateEmployee(EmployeeInfo objEmp)
    {
        objContext.AddToEmployeeInfoes(objEmp);
        objContext.SaveChanges();
    }

    public void UpdateEmployee(EmployeeInfo objEmp)
    {
        var Employee = objContext.EmployeeInfoes.First(e => e.EmpNo == objEmp.EmpNo);
        Employee.Salary = objEmp.Salary;
        Employee.DeptName = objEmp.DeptName;
        Employee.Designation = objEmp.Designation;
        objContext.SaveChanges();
    }

    public void DeleteEmployee(int EmpNo)
    {
        var Employee = objContext.EmployeeInfoes.First(e => e.EmpNo == EmpNo);
        objContext.DeleteObject(Employee);
        objContext.SaveChanges();
    }
}

The above code makes call to Database using methods provided by ADO.NET EF. Build the service and publish it on IIS.

Creating Silverlight 5 Application

Step 1: In the solution created above, add a new Silverlight 5.0 application and name it as ‘SL5_Xam_Grid_Programming’. Add a new Silverlight UserControl in this project and name it as ‘MainPage_XamGrid_Application_Dev’.

Step 2: To make use of the Infragistic controls sets for LOB applications, add the following references:

  • InfragisticsSL5.v12.1.dll - Represents an Infragistics framework for Controls and other features.
  • InfragisticsSL5.Controls.Grids.XamGrid.v12.1.dll - Represents library for xamGrid programming.
  • InfragisticsSL5.Controls.Grids.WordWriter.v12.1.dll - Library used for exporting data to Word.
  • InfragisticsSL5.Documents.IO.v12.1.dll - Library used Stream operations.
  • InfragisticsSL5.Compression.v12.1.dll - Contains the Silverlight compression library.
  • InfragisticsSL5.Persistence.v12.1.dll - Contains Infragistics control persistence framework.

Step 3: In the SL project, add a service reference to the WCF service created above.

Step 4: To add the xamGrid to the user control, add the XAML namespace in the <UserControl> as below:

xmlns:inf=”http://schemas.infragistics.com/xaml”

Add the xamGrid inside the <Grid> of name ‘LayoutRoot’ as below:

<inf:xamGrid x:Name="xamgrdEmpInfo" AutoGenerateColumns="False" Height="300" Margin="0,17,0,52"> </inf:xamGrid>

The xamGrid is set with ‘AutoGeneratedColumns’ to ‘False’, this means that the column definitions will need to be set explicitly. We have following types of Columns provided:

  • CheckboxColumn.
  • ComboboxColumn.
  • DateColumn.
  • DateTimeColumn.
  • GroupColumn.
  • HyperlinkColumn.
  • ImageColumn.
  • MultiColumnComboColumn.
  • SparkLineColumn.
  • TemplateColumn.
  • TextColumn.
  • UnboundColumn.

Most of the column types listed above are self-explanatory. Only the SparkLineColumn allows us to put SparkLine Chart in the xamGrid cell. The UnboundColumn allows us to put Command buttons for performing Edit, Delete Buttons.

Step 5: To define columns in the xamGrid, add the following Xaml:

<inf:XamGrid.Columns>
  <inf:TextColumn HeaderText="EmpNo" Key="EmpNo"  IsReadOnly="True">
  </inf:TextColumn>
    <inf:TextColumn HeaderText="EmpName" Key="EmpName"  
              AllowEditingValidation="True" IsReadOnly="False">
    </inf:TextColumn>
    <inf:TextColum HeaderText="Salary" Key="Salary" AllowEditingValidation="True"
        IsReadOnly="False">
    </inf:TextColumn>
    <inf:TextColumn HeaderText="DeptName" Key="DeptName" IsSortable="False"
        AllowEditingValidation="True" IsReadOnly="False">
    </inf:TextColumn>
    <inf:TextColumn HeaderText="Designation" Key="Designation" IsSortable="False"
        AllowEditingValidation="True" IsReadOnly="False">
    </inf:TextColumn>

The above xaml makes use of the TextColumn. This declares the ‘Key’ property which defines the DataField bound with the Column.

Step 6: Open the Code-Behind and write the following code:

MyRef.ServiceClient Proxy;

/// <summary>
/// Helper method to make the service call and fetch the Data
/// </summary>
private void LoadGrid()
{
    Proxy.GetEmployeesCompleted += Proxy_GetEmployeesCompleted;
    Proxy.GetEmployeesAsync();
}

void Proxy_GetEmployeesCompleted(object sender, MyRef.GetEmployeesCompletedEventArgs e)
{
    if (e.Result != null)
    {
        xamgrdEmpInfo.ItemsSource = e.Result;
    }
}

private void UserControl_Loaded_1(object sender, RoutedEventArgs e)
{
    Proxy = new MyRef.ServiceClient();
    LoadGrid();
}

Step 7: Run the application and the result will be as shown below:

I2_First_Result

Implementing Pagination

The Paging facility provided with the xamGrid control has the feature of dividing bound data into pages. xamGrid provides the ‘PagerSettings’ object. This object provides properties like ‘AllowPaging’ and ‘PageSize’. The number of pages are defined by the PageSize property. The ‘AllowPaging’ property sets the pagination and it also specifies the appearance of the pager for the xamGrid. The possible values for AllowPaging are ‘Both’, ‘Bottom’ ,’Hidden’ ,’None’ ,’Top’.

To implement paging, set the property as shown below:

<inf:XamGrid.PagerSettings>
     <inf:PagerSettings AllowPaging="Both" PageSize="5"/>
</inf:XamGrid.PagerSettings>

Run the application and the result is as shown below:

I3_Pagination

 

Implementing Filtering

In an LOB application, when you are displaying data in a Grid fashion, most of the times an end user wants functionality for filtering the data; so as to view only matching records in the Grid. xamGrid provides ‘FilteringSettings’ object which enables filtering on the Grid.

To set the property, just add the following Xaml under the XamGrid and the Grid takes care of the rest.

<inf:XamGrid.FilteringSettings>

<inf:FilteringSettings AllowFiltering="FilterRowTop" />

</inf:XamGrid.FilteringSettings>

Run the application and this is what you see

I4_Filtering_Res1

Click on the Filter for the DeptName column. You will see a textbox there. Just type in your search string inside the textbox and the matching data will be displayed as shown below:

 

I5_Filtering_Res2

Performing Edit, Delete and Add operations.

This is the one of the most exciting features of the xamGrid. If you are familiar with the Commanding features provided in an ASP.NET GridView and want a similar type of facility in Silverlight, then I must say that you must use the xamGrid. The Edit, Delete Commands provides a default mechanism to convert the Row in a Grid as Editable row and also delete the row when the Delete button is clicked. Of course you need to implement some events provided by xamGrid for performing Edit, Delete operations. The events are:

  • RowEnteringEditMode - Fires when Row is editable, this will takes place when edit command button is clicked.
  • RowExitingEditMode - Fires when end-user completes edit task and comes out of the row by using arrow keys or using TAB.
  • RowDeleting -  Fires when the Delete command button is clicked.
  • RowAdding -  Fires when end-user enters data in the New Blank Row and comes out of the row. Here first the RowExitingEditMode event is fired and then the RowAdding event is fired. So you need to make sure that the logic for adding is written properly.

Adding Command Buttons:

In the column collection of xamGrid, add an Unbound column, add a button inside it and then define the command as shown below:

<inf:UnboundColumn Key="Row Commands">
    <inf:UnboundColumn.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <Button Content="Edit" Width="40">
                <inf:Commanding.Command>
                    <inf:XamGridRowCommandSource EventName="Click"
                    AllowEventHandling="True" CommandType="Edit">
                </inf:XamGridRowCommandSource>
                </inf:Commanding.Command>
            </Button>
            <Button Content="Delete" Width="40">
                <inf:Commanding.Command>
                    <inf:XamGridRowCommandSource EventName="Click"
                    AllowEventHandling="True"  CommandType="Delete">
                </inf:XamGridRowCommandSource>
                </inf:Commanding.Command>
            </Button>
        </StackPanel>
    </DataTemplate>
    </inf:UnboundColumn.ItemTemplate>
</inf:UnboundColumn>

Inside the xamGrid tag add EditingSettings and AddNewRowSettings:

<inf:XamGrid.AddNewRowSettings>
    <inf:AddNewRowSettings AllowAddNewRow="Bottom"/>
</inf:XamGrid.AddNewRowSettings>
<inf:XamGrid.EditingSettings>
    <inf:EditingSettings AllowEditing="Row" />
</inf:XamGrid.EditingSettings>

xamGrid provides ‘AddNewRowTemplate’ and ‘AddNewRowEditorTemplate’ objects to provide DataBinding for the newly added row in the xamGrid, so you need to make changes in the ‘TextColumn’ as shown below:

<inf:TextColumn HeaderText="EmpName" Key="EmpName" AllowEditingValidation="True"
    IsReadOnly="False">
    <inf:TextColumn.AddNewRowItemTemplate>
    <DataTemplate>
    <TextBlock Text="Enter Name Here"/>
    </DataTemplate>
    </inf:TextColumn.AddNewRowItemTemplate>
    <inf:TextColumn.AddNewRowEditorTemplate>
    <DataTemplate>
    <TextBox Text="{Binding EmpName,Mode=TwoWay,UpdateSourceTrigger=Explicit,
        ValidatesOnExceptions=True,NotifyOnValidationError=True}"/>
    </DataTemplate>
    </inf:TextColumn.AddNewRowEditorTemplate>
</inf:TextColumn>

Similarly do it for Salary, DeptName and Designation

Writing code for Add, Edit and Delete operations

In the Xaml, add the following events in the xamGrid:

RowEnteringEditMode="xamgrdEmpInfo_RowEnteringEditMode_1"
     RowExitingEditMode="xamgrdEmpInfo_RowExitingEditMode_1"
     RowDeleting="xamgrdEmpInfo_RowDeleting_1"
     RowAdding="xamgrdEmpInfo_RowAdding_1"

and write code for these events. The code can be found in the solution file accompanied with this article.

Run the application:

I6_Edit_Delete_Add_New_Row_Item_Template

Click on ‘Edit’ and you will see the following:

I7_Edit_Command

 

After entering data in the editable cells, you can use the TAB key to exit the row and the data will be updated. Similarly by clicking on the Delete button, the record can be deleted. Likewise you can also use the Add functionality by clicking on the ‘AddNewRowTemplate’ “(Enter Name Here)” in the above figure.

Implementing Sorting

The xamGrid provides ‘SortingSettings’ object using which sorting on multiple columns can be made possible. Add the following Xaml inside xamGrid:

<inf:XamGrid.SortingSettings>
                <inf:SortingSettings AllowMultipleColumnSorting="True"/>  
</inf:XamGrid.SortingSettings>

Now run the application and the result will be as shown below:

I8_Column_Sorted

Click on the EmpNo and sort in descending order. The result will be as shown below:

I9_Sorting

Click on EmpName column and you will find the EmpNo sorted in descending order and EmpName in ascending order as shown below:

I10_Muliple_Column_Sort

So after going through all these features, one can say that these are some custom requirements in a LOB application which the Infragistics xamGrid makes it look so easy. By applying the IsSortable property to false on the column, you can prevent the column from getting sort.

Exporting XamGrid data to Word

Generating print based output was provided in Silverlight 4.0, but we can only print to XPS and the printing is based upon the Visual Elements we have on the UI. But if the requirement is such that the data present in the DataGrid is to be printed to an office document like Word or Excel, then it was a challenging task to accomplish in Silverlight 4.0.

With the Infragistics LOB toolset, the xamGrid has provided the facility of exporting Data to Word, Excel with minimal coding. We have been provided with XamGridWordWriter class which allows user to export data from xamGrid to Word as shown here:

Step 1: In the Xaml, add a Button as below:

<Button x:Name="btnExportToWord" Content="Export to Word" Click="btnExportToWord_Click_1"></Button>

Step 2: Open code-behind and declare the following objects at class level:

XamGridWordWriter xmgrdWrdWriter;
WordDocumentSettings wordDocSettings;
WordTableSettings wordTableSettings;
WordTableCellSettings wordTableCellSettings;

The settings classes are used to apply behavioral settings on the Word document e.g. Title, Author is provided by WordDocumentSettings class. Table settings e.g. border etc is provided by WordTableSettings class. Header style, cell style are provided by WordTableCellSettings class.

In the Loaded event, instantiate the objects as shown below:

xmgrdWrdWriter = new XamGridWordWriter();
wordDocSettings = new WordDocumentSettings();
wordTableSettings = new WordTableSettings();
wordTableCellSettings = new WordTableCellSettings();

Declare the helper method which will allow an end-user to create a new Word Document:

/// <summary>
/// Helper method which will provide SaveDialogBox
/// for Creating and Saving Word Document
/// </summary>
/// <returns></returns>
private Stream GetWordStreamForExport()
{
    //S1 : Declare SaveFileDialog
    SaveFileDialog saveFileDislog = new SaveFileDialog();
    saveFileDislog.Filter = "Word Doc(*.docx)|*.docx";
    //S2: Set the Default Extension for the file being Created and Saved
    saveFileDislog.DefaultExt = "docx";

    Stream Fs = null;
    if (saveFileDislog.ShowDialog() == true)
    {
        Fs = saveFileDislog.OpenFile();
    }
    return Fs;
}

The above code creates a new Word Document. Write the following code in the click event of the ‘Export to Word’ button. This applies various settings on the word document and the data from the xamGrid to the word document as shown below:

private void btnExportToWord_Click_1(object sender, RoutedEventArgs e)
{
    try
    {
        //Get the Stream
        Stream fs = GetWordStreamForExport();
        if (fs != null)
        {
            //Set Word Document Metadata
            wordDocSettings.Author = "Customer Management";
            wordDocSettings.Company = "My Company";
            wordDocSettings.Title = "Customer List";
            xmgrdWrdWriter.ExportLayoutSettings.WordDocumentSettings = wordDocSettings;

            //Set Table Settings
            wordTableSettings.BorderSettings = new WordBorderSettings() { Width = 5 };
            xmgrdWrdWriter.ExportLayoutSettings.DefaultTableSettings = wordTableSettings;

            //Set Table Cell Settings
            wordTableCellSettings.BackColor = Colors.Yellow;
            wordTableCellSettings.VerticalAlignment =
            Infragistics.Documents.Word.TableCellVerticalAlignment.Center;
            xmgrdWrdWriter.ExportLayoutSettings.HeaderRowTableCellSettings =
            wordTableCellSettings;
            //Exclude the UnBound Columns
            xmgrdWrdWriter.ExcludeUnboundColumns = true;
            xmgrdWrdWriter.Export(xamgrdEmpInfo, fs);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Run the application and click on the ‘Export to Word’ button. The result will be as below:

I11_Export_Tow_Wrod

Click on save and you will find the document created and the data exported in the Word document inside the Table

I12_Word_Exported

Conclusion:

The xamGrid provides features which caters to several requirements of an LOB application. The typical functionality of Commanding, Sorting and exporting to Word/Excel helps us to build real-world applications. Apart from the columns we explored, we also have the SparkLineColumn which allows us to display a chart inside the cell. There are many more features provided with Infragistics NetAdvantage Silverlight LOB toolkit which makes a developer’s life easy while developing LOB applications using Silverlight. Give it a try!

Download the source code

Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Hafaldo on Tuesday, June 19, 2012 5:13 AM
Hi Mahesh, I saw a barcode reader control in your product. What purpose does that control serve in a LOB application?
Comment posted by Jesús Paffue on Tuesday, June 19, 2012 8:38 PM
I tried your map control and like the overall features but the scrolling needs improvement
Comment posted by Brian Lagunas on Wednesday, June 20, 2012 12:50 PM
@Hafaldo Barcodes can be used for a variety of reasons in an LOB application.  I suggest reading up on barcodes http://en.wikipedia.org/wiki/Barcode

@Jesus Could you please provide more detail regarding the scrolling?
Comment posted by Loshan on Friday, June 22, 2012 1:46 PM
Nice walkthrough mahesh
Comment posted by Mahesh Sabnis on Saturday, June 23, 2012 6:02 AM
Hi All,
  Thanks a lot. I am currently exploring various other controls in NetAdvantages toolkit and will keep posting accordingly.
Regards
MAhesh Sabnis
Comment posted by Josh Hicks on Tuesday, July 10, 2012 8:38 AM
Thanks. This should be helpful in our sales app. Have you tried their chart controls? what's your take on that
Comment posted by Ral Hickey on Thursday, August 16, 2012 10:42 PM
Any idea if they are supporting VS 2012 RTM and 4.5? They do mention VS 2012 support on their site but it is RC or RTM they are supporting?

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel