我有一个WPF
DataGrid
它绑定到ViewModel,一切都很棒。我现在意识到我需要将更多的数据加载到
数据网格
比最初预期的要多。所以我用过
async
以使将该数据加载到Viewmodel容器中成为非UI阻塞。所以,在我的
ResourceDataViewModel : ViewModelBase
我有以下方法
public async void LoadResourceFilesAsync(string fullFileName = null)
{
if (!String.IsNullOrEmpty(fullFileName))
this.FullFileName = fullFileName;
strategy = manager.InitialiseStrategy(this);
if (strategy == null)
return;
...
// Get data asynchoniously.
List<ResourceViewModel> resourceViewModelList = await strategy.LoadResourceFilesAsync();
this.Resources = new TypedListObservableCollection<ResourceViewModel>(resourceViewModelList);
// Setup event handlers.
this.Resources.CollectionChanged += this.OnCollectionChanged;
foreach (ResourceViewModel rvm in resourceViewModelList)
rvm.PropertyChanged += this.OnResourceViewModelPropertyChanged;
// Set the file name for View and ViewModel.
this.FullFileName = strategy.FullFileName;
base.DisplayName = Path.GetFileName(this.FullFileName);
...
}
所以,在我做加载方法之前
异步
,一切都很好;数据已加载
DisplayName
(中定义的属性
abstract
ViewModelBase
类)绑定到
TabItem
header属性导致文件名显示在
标签项目
收割台正确。现在我已经使加载异步,数据加载到
数据网格
正如您从上面的代码中所期望的那样,
base.DisplayName = Path.GetFileName(this.FullFileName);
不更新
base.DisplayName
相反,它
默默地
(即在我的代码中不抛出和exeption)导致
System.ArgumentException
带有消息:
消息=“在对象实例上找不到方法。”
现在,我变了
base.DisplayName(基本显示名称)
到
**this**.DisplayName
这将停止异常,但仍然不会更新
标签项目
Header
,
为什么会发生这种情况,我该如何解决?
笔记我已经检查了执行此操作的线程,并且它是预期的MainThread/UIThread,这使得这非常不正常。
使现代化当我使用Snoop时,我已经用它来了解绑定发生了什么
this.DisplayName
装订正在显示
{DisconnectedItem}
(我发现了
related question at MSDN
). 然而,我仍然不知道这里发生了什么。。。
编辑地址注释
这个
DataContext
我的应用程序的主窗口是
MainWindowViewModel
; 这包含一个属性
public ObservableCollection<WorkspaceViewModel> Workspaces { ... }
其中包含我要在每个视图中显示的ViewModel
标签项目
。我有另一个ViewModel(称为ResourceDataViewModel
) which holds the
数据网格
s and inherits from
public WorkspaceViewModel`,定义为
public abstract class WorkspaceViewModel : ViewModelBase { ... }
并处理所有MVVM的东西,比如
OnPropertyChanged
处理程序等
主窗口视图模型
将资源文件加载到的调用层次结构
TabControl
在主窗口中是:
public void LoadResourceFiles(string fullFileName = null)
{
// Build and load the ViewModel in to the View.
ResourceDataViewModel workspace = new ResourceDataViewModel(this);
workspace.LoadResourceFilesAsync(fullFileName);
...
}
和在
ResourceDataViewModel
我有上面原始问题中显示的方法。然后,它从策略工厂获取策略,并异步加载数据——在本例中使用以下方法
public async Task<List<ResourceViewModel>> LoadResourceFilesAsync()
{
// Do preliminary work here [build FileCultureDictionary etc.].
...
// Build the resource data sets and return.
List<Resource> buildResult = await BuildResourceDataAsync(FileCultureDictionary);
return (from resource in buildResult
select new ResourceViewModel(resource)).ToList();
}
private async Task<List<Resource>> BuildResourceDataAsync(Dictionary<string, string> cultureDict)
{
// Now add the data.
int fileIndex = 1;
const int coreColumnIndex = 2;
string[] strArr = null;
List<string[]> strArrList = new List<string[]>();
// Start building the data.
Task<List<Resource>> task = Task.Factory.StartNew<List<Resource>>(() =>
{
// Do some work here...
...
return resources;
});
return await task;
}
注意,从这些方法返回的数据
很好。
这些方法本身似乎并没有造成上述问题——无论上下文切换可能是什么。我在这里真的很不知所措,所以任何想法都是最受欢迎的。