views:

2021

answers:

2

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);
}
+1  A: 

Do I understand that you want to control the visibility of auto-generated columns? I think the DataGrid's AutoGeneratingColumn event would be perfect for this. It fires once for each automatically generated column. You could modify the column's properties at this time (such as setting Visibility) or do e.Cancel = true to prevent creating that column at all.

Daniel Pratt
Yes - the columns on the DataGrid are created automatically from the columns in the DataTable. I'll investigate the AutoGeneratingColumn event
ChrisF
I actually needed to use the AutoGeneratedColumns event. This is actually raised twice so I needed to check the Columns.Count before trying to access the data.
ChrisF
A: 

I realised that the behaviour I was seeing was correct and I could only access the columns after Daniel's answer pointed me in the right direction (even though it wasn't 100% right). However, this then led to the subsequent problem with trying to set both the visibility and display index.

I reported the issue with not being able to set both the display index and visibility on the Codeplex discussion board and have just got back this reply:

This is a indeed a bug, and we've filed a bug in our database to track the issue.

You may try working around the issue by calling Dispatcher.BeginInvoke at Background priority within a Loaded event. It appears that the issue does not occur if the order is changed after the page has reached a steady state.

I'm not sure whether I'll check this work-around out or not. I was rewriting a WinForms app in WPF as a learning exercise and having this work isn't really essential to that.

UPDATE

I was using version 3.5.40320.1, labelled March 2009.

I've just updated to version 3.5.40619.1, labelled June 2009 and the problem with setting both the visibility and display index has been fixed.

ChrisF
I'm accepting my own answer as it explains the current position.
ChrisF