C# 从WPF中的任何线程修改Datagrid.Columns

C# 从WPF中的任何线程修改Datagrid.Columns,c#,wpf,datagrid,async-await,cross-thread,C#,Wpf,Datagrid,Async Await,Cross Thread,(我在Visual Studio 2017中使用.Net 4.5。文章末尾添加了最小示例链接,如果您想自己查看这些内容,可以在无需任何操作的情况下运行/崩溃) 我有一个UserControl,它在WPF中包含一个DataGrid。它绑定到一个Viewmodel,该Viewmodel包含一个DataTable和一个自定义列列表,以便在当前无法删除某些列时隐藏它们 DataGrid.Columns是只读的,因此在UserControl.DataContextChanged(我将在下面解释原因)中,我

(我在Visual Studio 2017中使用.Net 4.5。文章末尾添加了最小示例链接,如果您想自己查看这些内容,可以在无需任何操作的情况下运行/崩溃)

我有一个UserControl,它在WPF中包含一个DataGrid。它绑定到一个Viewmodel,该Viewmodel包含一个DataTable和一个自定义列列表,以便在当前无法删除某些列时隐藏它们

DataGrid.Columns是只读的,因此在UserControl.DataContextChanged(我将在下面解释原因)中,我获取新的DataContext,清除我的grid.Columns集合,并将加载时读取的DataGridColumns的自定义列表提供给它

起初,我正在进行同步加载。一切正常(我正在加载很多东西,包括这些项目的列表)。但我已经将加载放在backgroundworker中(运行几乎正常),之后,使用Task.Run()将backgroundworker替换为异步加载

我的窗口中的所有其他项目列表都加载良好,代码运行良好。但是,当我试图用其他列替换mygrid.Columns时,我有一个InvalidOperationException,表示调用线程无法访问该对象,因为它是另一个线程拥有的

我尝试了很多东西,很多都是从myGrid.Dispatcher、应用程序的当前Dispatcher等开始的,还有我找到的每一段异步代码,但我不知道如何向这个ObservableCollection添加一个简单的项

我见过自定义asyncObservableCollection,但不能使用它们,DataGrid.Columns是只读的

我感到困惑的是,我认为UserControl_DataContextChanged属于UI线程,因此它应该能够安全地更改用户控件

我已经在这里上传了一个“最小示例”=> 问题出在ItemViewmodel.FilterColumns中,正如我的原始代码所做的那样(希望此问题的解决方案也能在原始代码上工作)


如果您使用的是.Net 4.5或更高版本,我们将非常感谢您的帮助(我的英语很抱歉)

在窗口构造函数中:

// Sync collection with UI
BindingOperations.CollectionRegistering += BindingOperations_CollectionRegistering;
并添加此方法:

/// <summary>
/// Handles the CollectionRegistering event of the BindingOperations control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="CollectionRegisteringEventArgs"/> instance containing the event data.</param>
private void BindingOperations_CollectionRegistering(object sender, CollectionRegisteringEventArgs e)
{
    BindingOperations.EnableCollectionSynchronization(e.Collection, e.Collection);
}
//
///处理BindingOperations控件的CollectionRegistrating事件。
/// 
///事件的来源。
///包含事件数据的实例。
私有void BindingOperations\u CollectionRegistrating(对象发送方、CollectionRegisteringEventArgs e)
{
BindingOperations.EnableCollectionSynchronization(e.Collection,e.Collection);
}
这将在创建ObservableCollection时自动调用EnableCollectionSynchronization方法

我将它设置为只使用集合本身作为lockObject,不知道这是否是一个坏主意,但它在我这方面起了作用



如果您使用的是.Net 4.0,则可能需要启动该程序。在.Net 4.0中,我还没有找到其他方法来实现这一点。

感谢其他论坛的帮助,我找到了答案。 我把问题留在这里是因为很难找到答案

添加到DataGrid.Columns在viewmodel中手动实例化的DataGridColumn出现故障,应在UI线程中调用实例化本身。 Add抛出了一个异常,但主要是因为参数(在某些情况下是调用本身)


抱歉,再次声明,没有完整的代码引用,只有“belletristic小说”,但它可能会有所帮助

我们是这里的软件人,比您在这里发布的一本贝勒特斯小说更了解代码。。。如果你想要一个快速准确的答案,请提供一个答案。我上传了一个“最小的、完整的和可验证的示例”(但无法在我的帖子中写出全部代码),以便你能给我你的解决方案。提前感谢。-4如果我没有做任何研究工作或试图清楚地解释它,而我已经做了4天了,很好…这是多线程WPF应用程序中非常常见的问题。因此,有很多帮助可以找到。问题是你没有提供帮助你所需要的关键东西。例如.Net版本或简单的代码片段。实际上,我提供了您在编辑的文章中要求的最小示例。我现在要添加FW版本。不起作用:(我升级了一个“最小示例”here=>这是一个简化的代码,但它在ItemViewmodel.FilterColumns中失败,就像我的原始代码一样。你没有提到什么不起作用或你尝试了什么。我没有时间下载你的代码并测试它。之前的评论员要求我提供一些代码,这就是我上传它的原因。什么不起作用:我的代码,在ItemViewmodel.Fil中terColumns,当我尝试向集合添加项目时,与之前一样。相同错误。InvalidOperationException。无论如何,感谢您尝试帮助我:)