How to add DatePicker to DataGridTextColumn in WPF

<DataGrid Name="myfirstdg" Grid.Row="2" AutoGenerateColumns="False" CanUserSortColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" SelectionUnit="Cell" > <DataGrid.Columns> <DataGridTextColumn Header="Date" Binding="{Binding Path=date}" Width="SizeToCells" IsReadOnly="True" MinWidth="100"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> 

I have a simple dategrid with a DataGridTextColumn in it. How to add a Datepicker to my DataGridTextColumn?

+8
c # wpf wpf-controls wpfdatagrid datepicker
source share
3 answers

As Nitesh said, use a DataGridTemplateColumn

 <DataGridTemplateColumn Header="Pick a Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding myDate}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding myDate}" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> 
+21
source share

I put a DatePicker in every column of my datagrids, here is my helper method that I assign a DataGrid in the windows constructor. This method also cancels the generation for a complex object that will not render perfectly in the DataGrid.

Adapt as you wish!

 public MainWindow() { InitializeComponent(); myDataGrid.AutoGeneratingColumn += DataGridUtilities.dataGrid_AutoGeneratingColumn; } public static class DataGridUtilities { public static void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if (!IsTypeOrNullableOfType(e.PropertyType, typeof (String)) && !IsNullableOfValueType(e.PropertyType)) e.Cancel = true; else if (IsTypeOrNullableOfType(e.PropertyType, typeof (DateTime))) { DataGridTemplateColumn col = new DataGridTemplateColumn(); col.Header = e.Column.Header; FrameworkElementFactory datePickerFactoryElem = new FrameworkElementFactory(typeof (DatePicker)); Binding dateBind= new Binding(e.PropertyName); dateBind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; dateBind.Mode = BindingMode.TwoWay; datePickerFactoryElem.SetValue(DatePicker.SelectedDateProperty, dateBind); datePickerFactoryElem.SetValue(DatePicker.DisplayDateProperty, dateBind); DataTemplate cellTemplate = new DataTemplate(); cellTemplate.VisualTree = datePickerFactoryElem; col.CellTemplate = cellTemplate; e.Column = col;//Set the new generated column } } private static bool IsTypeOrNullableOfType(Type propertyType, Type desiredType) { return (propertyType == desiredType || Nullable.GetUnderlyingType(propertyType) == desiredType); } private static bool IsNullableOfValueType(Type propertyType) { return (propertyType.IsValueType || (Nullable.GetUnderlyingType(propertyType) != null && Nullable.GetUnderlyingType(propertyType).IsValueType)); } } 
+4
source share

This is based on @Guish's answer, but encapsulates it in a new column class.

 private void Grid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if (e.PropertyType == typeof(DateTime)) { e.Column = new DataGridDateTimeColumn((DataGridBoundColumn)e.Column); } } internal class DataGridDateTimeColumn : DataGridBoundColumn { public DataGridDateTimeColumn(DataGridBoundColumn column) { Header = column.Header; Binding = (Binding)column.Binding; } protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { var control = new TextBlock(); BindingOperations.SetBinding(control, TextBlock.TextProperty, Binding); return control; } protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) { var control = new DatePicker(); BindingOperations.SetBinding(control, DatePicker.SelectedDateProperty, Binding); BindingOperations.SetBinding(control, DatePicker.DisplayDateProperty, Binding); return control; } } 
+1
source share

All Articles