Sam
Sam

Reputation: 29009

WPF: How to use DatePicker in XAML-DataGrid

In a standanlone WPF app I got a DataGrid to enter some values. For text values this works nicely just like this:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding MyCollection}">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
    <DataGridTextColumn Header="Description" Binding="{Binding Description}"/>
  </DataGrid.Columns>
</DataGrid>

But now I'd like to enter some dates using a DatePicker instead of a text entry, but there is no or something similar.

So how do I get a DatePicker (or anything else) as entry field in the DataGrid?

Upvotes: 3

Views: 5305

Answers (2)

Guish
Guish

Reputation: 5160

I prefer using a code behind approach

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));
    }
}

Upvotes: 0

HCL
HCL

Reputation: 36775

Use the DataGridTemplateColumn. There in you can specify the templates for edit and normal state. Look at the example in the article. It will show you how to use.

Upvotes: 6

Related Questions