2013-09-08 17 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> 

Ho un semplice dategrid con un DataGridTextColumn in esso. Come aggiungo un Datepicker al mio DataGridTextColumn?Come aggiungere un DatePicker a DataGridTextColumn in WPF

+0

Utilizzare 'DataGridTemplateColumn'. – Nitesh

risposta

21

Come ha detto Nitesh, utilizzare 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

non mostra il selettore datetime in datagrid – SANDEEP

4

ho messo un DatePicker in ogni colonna dei miei DataGrids, qui è il mio metodo di supporto che assegno al DataGrid nel costruttore di Windows. Questo metodo cancella anche la generazione per oggetti complessi che non mostrerebbero grandi nel DataGrid.

Adatta come desideri!

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

Questa si basa sulla @ risposta di Guish ma incapsula in una nuova classe di colonna.

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

Risposta brillante, e ciò che lo rende davvero eccezionale è che è in una forma altamente riutilizzabile! Sarebbe ancora più prezioso se potessimo specificare se visualizzare la "Data", solo una parte in TextBlock (provata con un campo Date e aver ottenuto anche il tempo), o meglio ancora essere in grado di impostare StringFormat del Binding . –

+0

Ho notato anche qualcos'altro, se vai e modifica la data, il tasto [Invio] non funziona più (non impegna le modifiche), puoi ovviamente mettere a fuoco un altro campo o riga, ma questo sembra un po 'strano per il utenti. [Tab]/[BackTab] funzionano comunque. –