尽管设置了 DataContext,但我的 WPF 工具包 DataGrid 上的 Columns 属性未设置
我使用反射创建了一个 DataTable,以从类中获取属性,并将其设置为 Microsoft.Windows.Controls.DataGrid 的 DataContext:
// 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 包含 Title、Artist、BitRate、HasImage 等属性。
我试图在 DataTable 填充数据之前设置 DataGrid 中某些列的可见性。 但是,dataGridView.Columns 属性为 null。 如果我等到 DataTable 填充后,则设置 dataGridView.Columns 属性。
DataTable.Columns 属性是在填充表之前设置的。
将 DataTable 绑定到 DataGrid 时还需要做什么吗? 我无法在 XAML 中执行任何操作,因为我正在通过反射动态构建 DataTable。
编辑:
我已将代码移至 AutoGenerateColumns 事件处理程序(似乎被调用两次),因此只要检查 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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我是否理解您想要控制自动生成列的可见性? 我认为 DataGrid 的 AutoGenerateColumn 事件非常适合此目的。 它为每个自动生成的列触发一次。 此时您可以修改列的属性(例如设置可见性)或执行
e.Cancel = true
来阻止创建该列。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 的回答为我指明了正确的方向(尽管不是 100% 正确)后我才能访问这些列。 然而,这导致了随后尝试设置可见性和显示索引的问题。
我报告了无法在 Codeplex 讨论板上同时设置显示索引和可见性的问题,并且刚刚收到此答复:
我不确定是否会检查这个解决方法。 我正在 WPF 中重写一个 WinForms 应用程序作为学习练习,而这项工作对此并不重要。
更新
我使用的是版本 3.5.40320.1,标记为 2009 年 3 月。
我刚刚更新到版本 3.5.40619.1,标记为 2009 年 6 月,并且设置可见性和显示索引的问题已得到修复。
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:
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.