尽管设置了 DataContext,但我的 WPF 工具包 DataGrid 上的 Columns 属性未设置

发布于 2024-07-16 14:56:00 字数 2115 浏览 3 评论 0原文

我使用反射创建了一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生共白头 2024-07-23 14:56:00

我是否理解您想要控制自动生成列的可见性? 我认为 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.

过气美图社 2024-07-23 14:56:00

我意识到我看到的行为是正确的,只有在 Daniel 的回答为我指明了正确的方向(尽管不是 100% 正确)后我才能访问这些列。 然而,这导致了随后尝试设置可见性和显示索引的问题。

我报告了无法在 Codeplex 讨论板上同时设置显示索引和可见性的问题,并且刚刚收到此答复:

这确实是一个错误,我们已经
在我们的数据库中提交一个错误以进行跟踪
问题。

您可以尝试解决该问题
通过调用 Dispatcher.BeginInvoke
Loaded 中的后台优先级
事件。 看来这个问题确实
如果订单更改则不会发生
当页面达到稳定状态后
状态。

我不确定是否会检查这个解决方法。 我正在 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:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文