2013-12-02 3 views
0

Редактировать: столбцы известны только во время выполнения, и я почему-то строю данные в DataTable на лету.Как связать с конкретными объектами в DataGrid/DataTable

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

В коде для (для временной отладки) Я обрабатываю событие AutoGeneratingColumn и пытаюсь установить динамический тип столбца. Если есть тип комплекса:

public class BoolData 
{ 
    public bool Value { get; set; } 
    public Guid Id{ get; set; } 
} 

В коде позади для вида, я делаю это:

private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
{ 
    if (e.PropertyType == typeof(string)) 
    { 
     var col = new DataGridTextColumn {Binding = new Binding(e.PropertyName)}; 
     e.Column = col; 
     e.Column.Header = e.PropertyName; 
    } 
    else if (e.PropertyType == typeof(BoolData)) 
    { 
     var col = new DataGridCheckBoxColumn {Binding = new Binding(e.PropertyName + "." + "Value")}; 
     e.Column = col; 
     e.Column.Header = e.PropertyName; 
    } 
} 

Проблема заключается в том, что даже там, где я добавил MyBool объекты в DataTable, строка " MyNamespace.MBoolData "- это то, что находится в DataGrid, что означает, что первое предложение if if является единственным. Это как если бы DataGrid или DataTable вызывали ToString() на объекте, прежде чем пытаться его отобразить.

Итак, я думаю, мой вопрос: как создать динамический DataTable, содержащий сложные объекты, а затем привязать его.

ответ

0

Вам просто нужно определить свои столбцы в XAML и использовать DataGridTemplateColumn, чтобы определить, как должен выглядеть ваш сложный объект. На связанной странице есть полный пример кода, но это основные сведения ... вы определяете DataTemplate, чтобы точно описать, как должен выглядеть сложный объект в пользовательском интерфейсе, а затем вы можете установить его как значение для свойства DataGridTemplateColumn.CellTemplate.

+0

Столбцы известны только во время выполнения, и я почему-то строю данные в DataTable на лету. – RBT

0

Вы должны попробовать это прямо в своем XAML.

<DataGrid ItemsSource="{Binding YourDataSource}" AutoGenerateColumns="False" > 
    <DataGrid.Columns> 
     <DataGridTemplateColumn Header="TheHeaderNameOfYourColumn" Width="SizeToCells"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <CheckBox IsChecked="{Binding Value}"/> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 
+0

Столбцы известны только во время выполнения, и я почему-то строю данные в DataTable на лету. – RBT

0

Не зная имя столбца, вы должны создать шаблон в вашем DataGrid ресурс

<DataGrid> 
    <DataGrid.Resources> 
     <DataTemplate DataType="{x:Type my:BoolData}"> <!--where "my" points to the correct namespace--> 
      <CheckBox IsChecked="{Binding Value}"/> 
     </DataTemplate> 
    </DataGrid.Resources> 
</DataGrid> 
+0

Вот что я делаю, но в вопросе e.PropertyType ALWAYS равно typeof (string). Либо Datagrid, либо DataTable вызывает ToString в экземпляре BoolData и возвращает это, поэтому фактические объекты BoolData никогда не попадают в пользовательский интерфейс. – RBT

+0

Вы уверены, что ваш datatable правильно заполнен? Когда я пытаюсь с простым примером, тип данных правильно удаляется в методе OnAutogeneratingColumn. –

+0

Бит, который мне не хватало, заключается в том, что когда я добавлял DataColumns, я явно не задавал DataType, поэтому он по умолчанию был для String. – RBT

0

ОК, я понял, что этот вопрос. Если бы я вставил код для создания DataTable, кто-то, вероятно, заметил бы это.

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

Смежные вопросы