<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"/>
</DataGrid.Columns>
</DataGrid>
I have a simple DataGrid
with a DataGridTextColumn
in it. How do I add a Datepicker
to my DataGridTextColumn
?
我有一个简单的DataGrid,其中包含一个DataGridTextColumn。如何向DataGridTextColumn添加一个Datepicker ?
3 个解决方案
#1
22
As Nitesh said, use DataGridTemplateColumn
正如尼泰什所说,使用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>
#2
4
I put a DatePicker in every column of my datagrids, here is my helper method that I assign to the DataGrid
in the windows constructor. This method also Cancel generation for complex object that wouldn't show great in the DataGrid.
我在DataGrid的每一列中都放了一个DatePicker,这是我在windows构造函数中分配给DataGrid的助手方法。该方法还取消了在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));
}
}
#3
1
This builds on @Guish's answer but encapsulates it into a new column class.
这基于@Guish的答案,但将其封装到一个新的列类中。
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
22
As Nitesh said, use DataGridTemplateColumn
正如尼泰什所说,使用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>
#2
4
I put a DatePicker in every column of my datagrids, here is my helper method that I assign to the DataGrid
in the windows constructor. This method also Cancel generation for complex object that wouldn't show great in the DataGrid.
我在DataGrid的每一列中都放了一个DatePicker,这是我在windows构造函数中分配给DataGrid的助手方法。该方法还取消了在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));
}
}
#3
1
This builds on @Guish's answer but encapsulates it into a new column class.
这基于@Guish的答案,但将其封装到一个新的列类中。
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;
}
}