Я создал DataTable, используя отражение, чтобы получить свойства из моего класса и установить его как DataContext для моего 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 содержит такие свойства, как заголовок, исполнитель, BitRate, HasImage.
Я пытаюсь установить видимость определенных столбцов в DataGrid до того, как DataTable будет заполнен данными. Однако свойство dataGridView.Columns имеет значение null. Если я подожду, пока DataTable не будет заполнен, тогда свойство dataGridView.Columns будет установлено.
Свойство DataTable.Columns устанавливается до заполнения таблицы.
Нужно ли что-то еще делать при привязке DataTable к DataGrid? Я ничего не могу сделать в XAML, так как я динамически создаю DataTable с помощью отражения.
EDIT:
Я переместил код в обработчик событий AutoGeneratedColumns (который, кажется, вызывается дважды), так что пока я проверяю Columns.Count, я могу получить доступ к данным.
Однако я могу установить видимость столбца или индекс отображения, но не оба. Если я пытаюсь сделать то и другое, я получаю индекс вне диапазона исключений в другом месте в коде WPFToolkit DataGrid. У кого-нибудь есть идеи, почему?
Мой код:
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 - один из моих методов:
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);
}