2010-07-30 1 views
4

Это сводит меня с ума. Я создаю DataGrid в коде, а затем привязываю его к datatable. Это динамически, и строки и столбцы будут различны при каждом создании сетки.WPF DataGrid привязка к datatable

В основном я Переберите мои DataTable и создать DataGrid столбцов для каждого столбца, например:

private static void CreateDataGridColumns(DataGrid datagrid, Document doc) 
{ 
    if (doc == null) return; //return 

    datagrid.Columns.Clear(); 
    foreach (var item in doc.Keys) 
    { 
     var column = new DataGridTemplateColumn 
     { 
      Header = item, 
      CellTemplateSelector = new CustomRowDataTemplateSelector(), 
     }; 

     datagrid.Columns.Add(column); 
    } 
} 

Как вы можете видеть, я использую пользовательский селектор шаблона данных, так что я могу сделать клетку по-разному в зависимости от по его содержанию.

Вот селектор шаблона

public class CustomRowDataTemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate 
     SelectTemplate(object item, DependencyObject container) 
    { 
     FrameworkElement element = container as FrameworkElement; 

     var presenter = container as ContentPresenter; 
     var gridCell = presenter.Parent as DataGridCell; 

     if (element != null && item != null && gridCell != null) 
     { 
      var row = item as DataRow; 

      if (row != null) 
      { 
       var cellObject = row[gridCell.Column.DisplayIndex]; 

       //set template based on cell type 

       if (cellObject is DateTime) 
       { 
        return element.FindResource("dateCell") as DataTemplate; 
       } 

       return element.FindResource("stringCell") as DataTemplate; 
      } 


     } 

     return null; 
    } 
} 

Вот мой stringCell DataTemplate

<DataTemplate x:Key="stringCell"> 
    <StackPanel> 
     <TextBlock Style="{StaticResource cellStyle}" 
        Grid.Row="0" Grid.Column="0" 
        Text="{Binding Converter={StaticResource cellConverter}}" /> 
    </StackPanel> 
</DataTemplate> 

Проблема заключается в том, что селектор шаблона вызывается для каждой ячейки (как и ожидалось), но я не могу сказать какая ячейка это, поэтому я не знаю, как установить текст в TextBlock. Я бы хотел сделать что-то подобное

<DataTemplate x:Key="stringCell"> 
    <StackPanel> 
     <TextBlock Style="{StaticResource cellStyle}" 
        Grid.Row="0" Grid.Column="0" 
        Text="{Binding Path=Row[CellIndex], Converter={StaticResource cellConverter}}" /> 
    </StackPanel> 
</DataTemplate> 

Но для меня нет ничего доступного, чтобы получить CellIndex. Как я могу сделать что-то подобное этому, где я могу установить Path = Row [CellIndex]

ответ

-1

Не уверен, что вы пытаетесь достичь функционально. Вы можете уйти с этим в коде. Создайте класс более высокого уровня, CellClass, который имеет свойство DisplayValue. С реализацией даты и строки. Свяжите источник с CellClass с Path = DisplayValue. Вы даже можете создать список CellClasses и привязать к CellClass [0], CellClass [1] ... Знаете, это работает так, как я это делаю, но я не уверен, что он обеспечивает функциональность, которую вы ищете.

public abstract class CellClass 
    { 
     public abstract String DispValue { get; } 
    } 
    public class CellClassDate : CellClass 
    { 
     public override String DispValue { get ...; } 
     public DateTime DateValue { get .. set ... } 
    } 
    public class CellClassString : CellClass 
    { 
     public override String DispValue { get ...; } 
     public DateTime StringValue { get .. set ... } 
    } 
0

Вы можете попытаться создать привязку в коде. Что-то вроде этого должно работать

var bind = new Binding(gridCell.Column.Header.ToString()) 
bind.Mode = BindingMode.TwoWay; 
bind.Source = row; 
BindingOperations.SetBinding(YourTextBlock, TextBlock.TextProperty, bind);