WPF Custom Datagrid Control(Filterable)

Kailash Chandra Behera | Tuesday, February 21, 2017

Introduction

This blog demonstrates how to create custom data grid in WPF. This data grid has has feature to filter data.

Getting Started

This demonstration creates Custome DataGrid control using C# and inherited from base control System.Windoes.Controls.DataGrid.it filters the data based on the user inputs.This custom data grid class contains one public property named IsFilter enables DataGrid to Filterable, if IsFilter property is true, it shows text boxes( if datatype is string or int )and checkbox (if datatype is boolean) in each column header. Apart from this property it contains some other property as well and that are mentioned in the below.

  1. DataList:This properties is the object of ICollectionView. The IcollectionView interface belongs to System.ComponentModel. Its monst powerfull feature is, it enables collections to have the functionality of current record management,Custome sorting,filtering and grouping. The DataList Property contais items list binded with DataGrid and pases as items source of base DataGrid.
  2. SearchValue::- It is the private property whose value will be searched in the Data Grid. Data type is Object.
  3. ColumnName:It is also private property is column name of Custome Data Grid whose cell value will be searched. Data Type is string.
  4. IsFilter:Boolean data type, enable s DataGrid to Filterable.
Above mentioned properties are used for out side of Custom DataGrid class apart from that this class overrides two base class(Base DataGrid) functions, that is discussed in the below.
  1. OnInitialized: This function is used for initialize the properties.
  2. OnItemSourceChanged:In this function, templates are added in to the heade of each columns of Custome DataGrid such as TextBox or CheckBox control. If the data type of column is DagaGridTextColumn than TextBox will be added into the header or the data type f column is DataGridCheckBoxColumn than CheckBox will be added in the header.




Code Shippet

Below code example contains all the code to create Custom DataGrid control in WPF.
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Windows.Controls;  
 using System.Windows;  
 using System.Windows.Media;  
 using System.Windows.Controls.Primitives;  
 using System.IO;  
 using System.ComponentModel;  
 using System.Windows.Data;  
 using System.Reflection;  
 namespace FilterableGridInWpf  
 {  
   public class FilterableDataGrid : DataGrid  
   {  
     private ICollectionView Datalist { get; set; }  
     private object SearchValue { get; set; }  
     public string ColumnName { get; set; }  
     public bool IsFilter { get; set; }  
     public FilterableDataGrid()  
     {  
       this.IsFilter = false;  
     }  
     protected override void OnInitialized(EventArgs e)  
     {  
       base.OnInitialized(e);  
     }  
     protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)  
     {  
       Datalist = CollectionViewSource.GetDefaultView(newValue);  
       base.OnItemsSourceChanged(oldValue, Datalist);  
       if (this.IsFilter == true)  
       {  
         foreach (DataGridColumn DGC in this.Columns)  
         {  
           FrameworkElementFactory Factory = new FrameworkElementFactory(typeof(StackPanel));  
           FrameworkElementFactory LFactory = new FrameworkElementFactory(typeof(Label));  
           LFactory.SetValue(Label.ContentProperty, DGC.Header.ToString());  
           Factory.AppendChild(LFactory);  
           if (DGC.GetType().Name == "DataGridTextColumn")  
           {  
             FrameworkElementFactory TFactory = new FrameworkElementFactory(typeof(TextBox));  
             TFactory.SetValue(TextBox.MarginProperty, new Thickness(0));  
             TFactory.SetValue(TextBox.WidthProperty, 150.00);  
             TFactory.SetValue(TextBox.NameProperty, "txt" + DGC.Header.ToString());  
             TFactory.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBox_TextChanged), false);  
             Factory.AppendChild(TFactory);  
           }  
           if (DGC.GetType().Name == "DataGridCheckBoxColumn")  
           {  
             FrameworkElementFactory TFactory = new FrameworkElementFactory(typeof(CheckBox));  
             TFactory.SetValue(CheckBox.NameProperty, "txt" + DGC.Header.ToString());  
             TFactory.AddHandler(CheckBox.ClickEvent, new RoutedEventHandler(CheckBox_Checked), false);  
             Factory.AppendChild(TFactory);  
           }  
           DataTemplate Template = new DataTemplate();  
           Template.DataType = typeof(HeaderedContentControl);  
           Template.VisualTree = Factory;  
           DGC.HeaderTemplate = Template;  
         }  
       }  
     }  
     void CheckBox_Checked(object sender, RoutedEventArgs e)  
     {  
       CheckBox CB = (CheckBox)sender;  
       this.SearchValue = CB.IsChecked;  
       ContentPresenter CP = (ContentPresenter)CB.TemplatedParent;  
       DataGridColumnHeader DGCH = (DataGridColumnHeader)CP.TemplatedParent;  
       DataGridColumn DGC = DGCH.Column;  
       this.ColumnName = DGC.Header.ToString();  
       this.Datalist.Filter = this.CustomeFilter;  
     }  
     private void TextBox_TextChanged(object sender, RoutedEventArgs e)  
     {  
       TextBox STB = (TextBox)sender;  
       this.SearchValue = STB.Text;  
       ContentPresenter CP = (ContentPresenter)STB.TemplatedParent;  
       DataGridColumnHeader DGCH = (DataGridColumnHeader)CP.TemplatedParent;  
       DataGridColumn DGC = DGCH.Column;  
       this.ColumnName = DGC.Header.ToString();  
       this.Datalist.Filter = this.CustomeFilter;  
     }  
     private bool CustomeFilter(object item)  
     {  
       Type TP = item.GetType();  
       PropertyInfo PI = TP.GetProperty(this.ColumnName);  
       object[] obj=new object[ this.SearchValue.ToString().Length];  
       string values = PI.GetValue(item,obj).ToString();  
       values = values.ToUpper();  
       return values.StartsWith(this.SearchValue.ToString().ToUpper());  
     }  
   }  
 }  

Related Articles

  1. Data Validation in WPF
  2. WPF Round Corner Button with click effects
  3. Round Corner PasswordBox in WPF
  4. Round Corner TextBox in WPF
  5. WPF Custom Datagrid Control(Filterable)
  6. WPF Round Corner ListBox
  7. Custom RadioButtonListBox With Image
  8. RadiobuttonList in WPF
  9. Custom CheckedListBox in WPF

Summary

Hope this article may be helpful to you, happy coding and enjo......y.

Thanks