2013-09-08 43 views
8
<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> 

Mam proste dategrid z DataGridTextColumn w nim. Jak dodać Datepicker do mojej DataGridTextColumn?Jak dodać DatePicker do DataGridTextColumn w WPF

+0

Użyj 'DataGridTemplateColumn'. – Nitesh

Odpowiedz

21

Jak powiedział Nitesh użyć 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> 
+0

to nie pokazuje wyboru datetime w datagrid – SANDEEP

4

kładę datepicker w każdej kolumnie moich datagrids, tu jest moja metoda pomocnika że przypisanie do DataGrid w konstruktorze okna. Ta metoda również anuluje generowanie złożonego obiektu, który nie byłby zbyt dobry w DataGrid.

Dostosuj się, jak chcesz!

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

To opiera się na odpowiedzi @ Guish, ale zamyka ją na nową klasę kolumny.

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; 
    } 
} 
+0

Znakomita odpowiedź, a to, co czyni ją naprawdę świetną, to to, że jest w formie wielokrotnego użytku! Byłoby jeszcze bardziej cenne, gdybyśmy mogli określić, czy wyświetlić "Date" - tylko część w TextBlock (wypróbowaliśmy to za pomocą pola tabeli Date i otrzymaliśmy również czas), czy jeszcze lepiej móc ustawić StringFormat of Binding . –

+0

Zauważyłem też coś innego, jeśli przejdziesz do edycji daty, klawisz [Enter] nie będzie działał (nie będzie zatwierdzać zmian), możesz oczywiście ustawić inne pole lub wiersz, ale to wygląda trochę dziwnie użytkowników. [Tab]/[BackTab] działają. –