Silverlight 4: Hide/Unhide DataGrid Columns

Silverlight DataGrid is a nice control provided for Data representation as well as manipulation. Since this control provides its object model separately e.g. DataGridColumn, DataGridColumnHeader etc, it is very easy for us to provide custom data representation capability to this control. In this article, I have demonstrated how to hide/unhide DataGrid columns depending on the user selection. This caters to requirements where the end-user wants to see only selected data column values from the source.

Step 1: Open VS 2010 and create Silverlight 4 project. Name it as ‘SL4_Hiding_Unhiding_DataGrid_Columns’. To this project, add the following classes. These classes will be used as a data source.

/// <summary>
/// Class containing Employee Details
/// </summary>
public class Employee
{
    public int EmpNo { get; set; }
    public string EmpName { get; set; }
    public string DeptName { get; set; }
    public string Designation { get; set; }
    public decimal Salary { get; set; }
}

/// <summary>
/// Class contains Employee Collection
/// </summary>
public class EmployeeCollection : ObservableCollection<Employee>
{
public EmployeeCollection()
{
    Add(new Employee() { EmpNo = 101, EmpName = "Ram",
        DeptName = "Admin", Designation = "Supreme", Salary = 890000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Bharat",
        DeptName = "Treasury", Designation = "Head", Salary = 390000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Lakshman",
        DeptName = "Security", Designation = "Head", Salary = 290000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Shatrugnaha",
        DeptName = "External Affairs", Designation = "CEO", Salary = 790000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Kirshna",
        DeptName = "Admin", Designation = "Supreme", Salary = 190000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Balram",
        DeptName = "Security", Designation = "Head", Salary = 390000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Gautam",
        DeptName = "Education", Designation = "Supreme", Salary = 790000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Bhargav",
        DeptName = "Security", Designation = "Head", Salary = 990000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Vaman",
        DeptName = "Education", Designation = "Head", Salary = 190000 });
    Add(new Employee() { EmpNo = 101, EmpName = "Udhav",
        DeptName = "External Affairs", Designation = "Head", Salary = 290000 });
}
}



Step 2: In the MainPage.xaml.cs, add a class for storing MetaInfo of the Employee class. This class we will be used to read all public property names in the Employee class. This class will be further used for binding with the ListBox. The end user will select property name from this list box to hide column. The class code is as shown below:

image

Step 3: In the MainPage.Xaml.cs and in the MainPage class, declare the List<ColumnDetails> object. Also write the following method which will read the Employee class using ‘typeof’ operation (Reflection in short) and load its properties in List< ColumnDetails >. The code is as below:

image

and here’s the method:

image

Step 4: In the MainPage.xaml write the following xaml:

<UserControl x:Class="SL4_Hiding_Unhiding_DataGrid_Columns.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="458" d:DesignWidth="844"
             xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
             Loaded="UserControl_Loaded">
    <UserControl.Resources>
        <DataTemplate x:Key="ColumnNameTemplate">
                <CheckBox Width="140" IsChecked="{Binding IsSelected}"
                          Content="{Binding ColumnName}" Click="chBkx_Click"></CheckBox>
        </DataTemplate>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="54*" />
            <RowDefinition Height="404*" />
        </Grid.RowDefinitions>
        <TextBlock Name="textBlock1" Text="Employee Information" TextAlignment="Center"
    FontSize="40" />
        <sdk:DataGrid AutoGenerateColumns="False" Grid.Row="1" Height="359"
                      HorizontalAlignment="Left" Margin="29,23,0,0" Name="dgEmp"
                      VerticalAlignment="Top" Width="620" ColumnWidth="*">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Header="EmpNo" Binding="{Binding EmpNo}">
        </sdk:DataGridTextColumn>
                <sdk:DataGridTextColumn Header="EmpName" Binding="{Binding EmpName}">
        </sdk:DataGridTextColumn>
                <sdk:DataGridTextColumn Header="DeptName" Binding="{Binding DeptName}">
        </sdk:DataGridTextColumn>
                <sdk:DataGridTextColumn Header="Designation" Binding="{Binding Designation}">
        </sdk:DataGridTextColumn>
                <sdk:DataGridTextColumn Header="Salary" Binding="{Binding Salary}">
        </sdk:DataGridTextColumn>
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <TextBlock Grid.Row="1" Height="38" HorizontalAlignment="Left" Margin="661,23,0,0"
                   Name="textBlock2" Text="Please Uncheck the Column to Hide:"
            VerticalAlignment="Top"
                   Width="125" TextWrapping="Wrap" />
        <ListBox Grid.Row="1" Height="228" HorizontalAlignment="Right" Margin="0,67,52,0"
                 Name="lstEmployeeColumns" VerticalAlignment="Top" Width="131"
                  ItemTemplate="{StaticResource ColumnNameTemplate}" />
     
    </Grid>
</UserControl>



Step 5: Declare the following object in the MainPage class level and in the Loaded event of the MainPage user control, write the following code:

EmployeeCollection EmpCol;
CheckBox chBkx;

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    EmpCol = new EmployeeCollection();
    //Bind EmployeeCollection to DataGrid
    dgEmp.ItemsSource = EmpCol;
    LoadListWithClassProperties();
    //Bind the ColumnName collection to ListBox
    lstEmployeeColumns.ItemsSource = PropertyDetails;
}



The above code binds the EmployeeCollection object to the DataGrid and also makes a call to the LoadListWithClassProperties() method. Finally it binds the PropertyDetails List object to the ListBox.

Step 6: If you see the above Xaml, it defines the DataTemplate of the name ‘ColumnNameTemplate’. This defines CheckBox and implements the ‘Click’ event. This DataTemplate is passed to the ListBox to display all properties from Employee class with checkboxes. Write the Click event in the code-behind for this checkbox. The code Is as below:

    /// <summary>
        /// The logic for hinding/Unhiding the columns from DataGrid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void chBkx_Click(object sender, RoutedEventArgs e)
        {
            chBkx = sender as CheckBox;
            bool isChecked = Convert.ToBoolean(chBkx.IsChecked);
            if (isChecked == false)
            {
                foreach (DataGridColumn dgColumn in dgEmp.Columns)
                {
                    if (dgColumn.Header.ToString() == chBkx.Content.ToString())
                    {
                        dgColumn.Visibility = System.Windows.Visibility.Collapsed;
                        break;
                    }
                }
            }
            if (isChecked == true)
            {
                foreach (DataGridColumn dgColumn in dgEmp.Columns)
                {
                    if (dgColumn.Header.ToString() == chBkx.Content.ToString())
                    {
                        dgColumn.Visibility = System.Windows.Visibility.Visible;
                        break;
                    }
                }
            }
        }
    }

The above code is the heart of the article. When the user deselects any checkbox from the ListBox, the DataGridColumn having header matching the property name will be hidden. When the user checks the checkbox, the matching DataGridColumn again gets displayed.

Step 7: Run the application and the initial screen will be as below:

clip_image002

From the ListBox deselect the ‘DeptName’ and the result will be as shown below:

clip_image004
Select the DeptName column again and here’s the result:

clip_image006






About The Author

Mahesh Sabnis is a Microsoft MVP having over 18 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). He also blogs regularly at DotNetCurry.com. Follow him on twitter @maheshdotnet

No comments: