I've created a DataTable using reflection to get the properties from my class and set this as the DataContext for my Microsoft.Windows.Controls.DataGrid:
// Create the columns based on the data in the album info - get by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();
dataTable.TableName = t.Name;
foreach (PropertyInfo p in t.GetProperties())
{
var columnSpec = new DataColumn();
// If boolean or int type can create directly into grid, else create a text box
if (p.PropertyType == typeof(bool) || p.PropertyType == typeof(int))
{
columnSpec.DataType = p.PropertyType;
}
else
{
columnSpec.DataType = typeof(string);
}
columnSpec.ColumnName = p.Name;
dataTable.Columns.Add(columnSpec);
}
dataGridView.DataContext = dataTable;
AlbumInfo contains properties such as Title, Artist, BitRate, HasImage.
I'm trying to set the visibility of certain columns in the DataGrid before the DataTable is filled with data. However, the dataGridView.Columns property is null. If I wait until after the DataTable is filled then the dataGridView.Columns property is set.
The DataTable.Columns property is set before the table is filled.
Is there anything else I need to do when binding the DataTable to the DataGrid? I can't do anything in the XAML as I'm building the DataTable dynamically via reflection.
EDIT:
I've moved the code to the AutoGeneratedColumns event handler (which seems to get called twice) so as long as I check the Columns.Count I can access the data.
However, I can either set the column visibility or display index - but not both. If I try to do both I get an index out of range exception elsewhere in the WPFToolkit DataGrid code. Anyone have any ideas why?
My code is:
foreach (object columnData in Properties.Settings.Default.ColumnData)
{
DataGridColumn column = dataGridView.Columns[index];
column.DisplayIndex = columnData.DisplayIndex;
column.Visibility = columnData.Visible ? Visibility.Visible : Visibility.Hidden;
AddContextMenuItem(dataGridView.ContextMenu, columnData.Header, index++, columnData.Visible);
}
AddContextMenuItem is one of my methods:
private void AddContextMenuItem(ContextMenu contextMenu, string columnName, int index, bool visible)
{
var menuItem = new MenuItem() { Header = columnName, Tag = index, IsCheckable = true, IsChecked = visible };
menuItem.Click += new RoutedEventHandler(contextMenu_onClick);
contextMenu.Items.Add(menuItem);
}