Add Checkbox In WPF Datagrid DatagridTemplateColumnHeader (For Checkall)
Hello,
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:
Note: You may add values after creating the table.
2. Change the App.config with your database settings.
3. Update your xaml and classes as presented below.
Here is the DataGrid xaml:
Main Window class:
Database Manipulation class:
Sample Output:
a. On form load (some of the checkbox are set to true, others are false)
b. Checkbox in column header is selected
c. Checkbox in column header is deselected
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
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>
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>
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 }
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)
b. Checkbox in column header is selected
c. Checkbox in column header is deselected
Could u send me whole project..
ReplyDeleteBecause 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
Hi,
ReplyDeleteThe methods used in this tutorial doesn't use third party dlls. Just pure WPF namespace. It should work just fine.
:)
Where is GetDatagridrows function....
ReplyDeleteHi!
DeleteHere's the reference when I created the GetDataGridRows() function.
http://techiethings.blogspot.com/2010/05/get-wpf-datagrid-row-and-cell.html
Cheers!
hello can u send that project or post
ReplyDeleteHi,
DeleteI already updated this post with the detailed source code.
Cheers..
great, works, thanks!
ReplyDeleteHi Igor,
DeleteYour welcome! :)
Greg
It helped me a lot. Many thanks!!! \0/
ReplyDeleteYour Welcome.. :)
Delete