如何在 WPF 中将 DatePicker 添加到 DataGridTextColumn
Posted
技术标签:
【中文标题】如何在 WPF 中将 DatePicker 添加到 DataGridTextColumn【英文标题】:How to add a DatePicker to DataGridTextColumn in WPF 【发布时间】:2013-09-11 20:53:51 【问题描述】:<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>
我有一个简单的DataGrid
,里面有一个DataGridTextColumn
。如何将Datepicker
添加到我的DataGridTextColumn
?
【问题讨论】:
使用DataGridTemplateColumn
。
【参考方案1】:
正如 Nitesh 所说,使用 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>
【讨论】:
一点用处都没有。 这可能有效,但它似乎不是复制/粘贴工作,因为myDate
超出范围 - 所有其他列都可以在 DataGrid 绑定的上下文中定义,但是在此模板中,DataContext 发生变化,myDate
无法解析。我想获得正确的绑定上下文是另一个故事
我不知道你的问题出在哪里,但这个答案对我很有用。数据上下文没有问题。【参考方案2】:
我在数据网格的每一列中都放置了一个 DatePicker,这是我在 windows 构造函数中分配给 DataGrid
的辅助方法。此方法还可以取消在 DataGrid 中显示效果不佳的复杂对象的生成。
随心所欲!
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】:这建立在@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();
control.PreviewKeyDown += Control_PreviewKeyDown;
BindingOperations.SetBinding(control, DatePicker.SelectedDateProperty, Binding);
BindingOperations.SetBinding(control, DatePicker.DisplayDateProperty, Binding);
return control;
private void Control_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
if (e.Key == System.Windows.Input.Key.Return)
DataGridOwner.CommitEdit();
【讨论】:
绝妙的答案,让它真正伟大的是它采用高度可重用的形式!如果我们可以指定是否在 TextBlock 中显示仅“日期”部分(尝试使用日期表字段并获得时间),或者更好的是能够设置绑定的 StringFormat,那将更有价值. 我也注意到了一些其他的事情,如果你去编辑日期,[Enter] 键不再起作用(它不会提交更改),你当然可以关注另一个字段或行,但这对用户来说有点奇怪。 [Tab]/[BackTab] 确实有效。 @Constantine Georgiou,我用 [Enter] 键解决了这个问题。感谢您的报告。以上是关于如何在 WPF 中将 DatePicker 添加到 DataGridTextColumn的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS7 中将 UIDatePicker 添加到 UIALertView