Donate

Add Checkbox In WPF Datagrid DatagridTemplateColumnHeader (For Checkall)

Hello,

Here's how to add checkbox in WPF Datagrid DatagridTemplateColumn to simulate checkall. I have included the TSQL script, XAML and C# codes.


Perform these steps below
1. Create an MSSQL database with the following Product Table schema below:
Table: Products
Fields:
-    ProductID (int, autoincrement)
-    ProductName (varchar)
-    UnitPrice (decimal)
-    QuantityPerUnit (varchar)
-    Discontinue (bit) 
SQL Script:
USE [Your_Database_Name]  
 GO  
 /****** Object: Table [dbo].[Products]  Script Date: 05/27/2013 14:07:39 ******/  
 SET ANSI_NULLS ON  
 GO  
 SET QUOTED_IDENTIFIER ON  
 GO  
 SET ANSI_PADDING ON  
 GO  
 CREATE TABLE [dbo].[Products](  
      [ProductID] [int] NOT NULL,  
      [ProductName] [varchar](50) NULL,  
      [UnitPrice] [decimal](18, 2) NULL,  
      [QuantityPerUnit] [varchar](50) NULL,  
      [Discontinue] [bit] NULL,  
  CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED   
 (  
      [productID] ASC  
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]  
 ) ON [PRIMARY]  
 GO  
 SET ANSI_PADDING OFF  
 GO  
Note: You may add values after creating the table.

2. Change the App.config with your database settings.
<?xml version="1.0"?>   
  <configuration>   
  <connectionStrings>   
   <add name="products"   
    connectionString="data source=testPC\SQLEXPRESS;Initial Catalog=your_test_database;User ID=your_user_id;Password=your_password;"   
    providerName="System.Data.SqlClient" />   
  </connectionStrings>   
  <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>   
3. Update your xaml and classes as presented below.
Here is the DataGrid xaml:
<DataGrid Name="dgProducts" AutoGenerateColumns="False" Grid.Row="1" Grid.RowSpan="3" Grid.ColumnSpan="2" CanUserAddRows="False">    
    <DataGrid.Columns>    
    <DataGridTextColumn Header="Name" Binding="{Binding Path=ProductName}" Width="215"/>    
    <DataGridTextColumn Header="Price" Binding="{Binding Path=UnitPrice}"/>    
    <DataGridTextColumn Header="Quantity Per Unit" Binding="{Binding Path=QuantityPerUnit}" Width="180"/>    
    <DataGridTemplateColumn>    
     <DataGridTemplateColumn.Header>    
     <CheckBox Content="Discontinue All" Click="CheckBox_Click" />    
     </DataGridTemplateColumn.Header>    
     <DataGridTemplateColumn.CellTemplate>    
     <DataTemplate>    
      <CheckBox Name="chkDiscontinue" IsChecked="{Binding Path=Discontinue,Mode=TwoWay}" Margin="45 2 0 0" Click="chkDiscontinue_Click" />    
     </DataTemplate>    
     </DataGridTemplateColumn.CellTemplate>    
    </DataGridTemplateColumn>    
    </DataGrid.Columns>    
   </DataGrid>    
Main Window class:
public partial class MainWindow : Window
{
 public MainWindow()
 {
  InitializeComponent();
 }

 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
  dgProducts.ItemsSource = Connections.GetProduct().AsDataView();
 }

 /// <summary>
 /// check all checkbox
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void CheckBox_Click(object sender, RoutedEventArgs e)
 {
  var row = GetDataGridRows(dgProducts);

  if (((CheckBox)sender).IsChecked == true)
  {
   SetCheckbox(row, true);
  }
  else
  {
   SetCheckbox(row, false);
  }
 }

 //individual checking
 private void chkDiscontinue_Click(object sender, RoutedEventArgs e)
 {
  object a = e.Source;
  CheckBox chk = (CheckBox)sender;

  DataGridRow row = FindAncestor<DataGridRow>(chk);
  if (row != null)
  {
   DataRowView rv = (DataRowView)row.Item;
   
   //LINQ or Database Method to Update Product discontinue status
   Connections.UpdateProductDiscontinue((bool)chk.IsChecked, rv["ProductName"].ToString());
  }
 }
 
 private void SetCheckbox(IEnumerable<DataGridRow> row, bool value)
 {
  //loop through datagrid rows
  foreach (DataGridRow r in row)
  {
   DataRowView rv = (DataRowView)r.Item;
   foreach (DataGridColumn column in dgProducts.Columns)
   {
    if (column.GetType().Equals(typeof(DataGridTemplateColumn)))
    {
     rv.Row["Discontinue"] = value;

     //LINQ or Database Method to Update Product discontinue status
     Connections.UpdateProductDiscontinue(value, rv.Row["productname"].ToString());                                                
    }
   }
  }
 }

 public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
 {
  var itemsSource = grid.ItemsSource as IEnumerable;
  if (null == itemsSource) yield return null;
  foreach (var item in itemsSource)
  {
   var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
   if (null != row) yield return row;
  }
 }

 #region visual tree helpers

 /// <summary>
 /// Returns the first ancester of specified type
 /// </summary>
 public static T FindAncestor<T>(DependencyObject current) where T : DependencyObject
 {
  current = VisualTreeHelper.GetParent(current);
  while (current != null)
  {
   if (current is T)
   {
    return (T)current;
   }

   current = VisualTreeHelper.GetParent(current);
  };
  return null;
 }

 private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
 {
  for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
  {
   DependencyObject child = VisualTreeHelper.GetChild(obj, i);
   if (child != null && child is childItem)
    return (childItem)child;
   else
   {
    childItem childOfChild = FindVisualChild<childItem>(child);
    if (childOfChild != null)
     return childOfChild;
   }
  }
  return null;
 }       

 #endregion
}
Database Manipulation class:
class Connections
{
 public static DataTable GetProduct()
 {
  DataSet ds = new DataSet();
  string query = "Select * from Products;";                    
   
  try
  {
   using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["products"].ConnectionString.ToString()))
   {
    SqlCommand cmd = new SqlCommand(query, conn);
    conn.Open();
    SqlDataAdapter da = new SqlDataAdapter(cmd);                    
    da.Fill(ds);
    conn.Close();
   }
  }
  catch (Exception ex)
  {
   throw ex;   
  }            
  return ds.Tables[0];
 }

 public static int UpdateProductDiscontinue(bool value, string product_name)
 {
  int result = 0;
  string query = String.Format("Update Products set discontinue = '{0}' where productname = '{1}' ;",value,product_name);

  try
  {
   using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["products"].ConnectionString.ToString()))
   {
    SqlCommand cmd = new SqlCommand(query, conn);
    conn.Open();
    result = cmd.ExecuteNonQuery();
    conn.Close();
   }
  }
  catch (Exception ex)
  {
   throw ex;
  }
  return result;
 }
}

Sample Output:
a. On form load (some of the checkbox are set to true, others are false)
Add Checkbox In WPF Datagrid DatagridTemplateColumnHeader (For Checkall)

b. Checkbox in column header is selected
Add Checkbox In WPF Datagrid DatagridTemplateColumnHeader (For Checkall)

c. Checkbox in column header is deselected
Add Checkbox In WPF Datagrid DatagridTemplateColumnHeader (For Checkall)

Comments

  1. Could u send me whole project..
    Because above code giving error may be required namespace are not referenced in my project..
    so please send that project in my mail ID

    AviSatna@gmail.com

    ReplyDelete
  2. Hi,

    The methods used in this tutorial doesn't use third party dlls. Just pure WPF namespace. It should work just fine.

    :)

    ReplyDelete
  3. Where is GetDatagridrows function....

    ReplyDelete
    Replies
    1. Hi!
      Here's the reference when I created the GetDataGridRows() function.

      http://techiethings.blogspot.com/2010/05/get-wpf-datagrid-row-and-cell.html

      Cheers!

      Delete
  4. hello can u send that project or post

    ReplyDelete
    Replies
    1. Hi,

      I already updated this post with the detailed source code.

      Cheers..

      Delete
  5. great, works, thanks!

    ReplyDelete
  6. It helped me a lot. Many thanks!!! \0/

    ReplyDelete

Post a Comment

Donate

Popular Posts From This Blog

WPF CRUD Application Using DataGrid, MVVM Pattern, Entity Framework, And C#.NET

TypeScript Error Or Bug: The term 'tsc' is not recognized as the name of a cmdlet, function, script file, or operable program.

Invalid nested tag div found, expected closing tag input