我有一个DataGrid
绑定到 ViewModel 的 WPF,一切都很好。我现在意识到我需要加载DataGrid
比最初预期更多的数据。所以我习惯于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);
...
}
所以,在我制作加载方法之前async
,一切都很好;数据已加载,并且绑定到标题属性的DisplayName
(类中定义的属性)导致文件名正确显示在标题中。现在我已经使加载异步,数据加载到罚款中,正如你所期望的那样,来自上面的代码,但是,abstract
ViewModelBase
TabItem
TabItem
DataGrid
base.DisplayName = Path.GetFileName(this.FullFileName);
不更新base.DisplayName
而是静默(即在我的代码中不抛出和异常)导致System.ArgumentException
带有消息:
Message = "在对象实例上找不到方法。"
现在,我已更改base.DisplayName
为**this**.DisplayName
,这停止了异常,但仍然没有更新TabItem
Header
,为什么会发生这种情况,我该如何解决?
笔记。我已经检查了它正在执行的线程,它是预期的 MainThread/UIThread,这使得这非常反常。
更新。this.DisplayName
当我使用并且绑定显示时,我使用 Snoop 来了解绑定发生的情况{DisconnectedItem}
(我在 MSDN 找到了一个相关问题)。然而,我仍然对这里发生的事情感到茫然......
编辑地址评论
我的DataContext
应用程序 MainWindow 是MainWindowViewModel
;这包含一个属性
public ObservableCollection<WorkspaceViewModel> Workspaces { ... }
其中包含我想在每个TabItem
. 我有另一个 ViewModel(称为 ResourceDataViewModel ) which holds the
DataGrid s and inherits from
public WorkspaceViewModel`,它被定义为
public abstract class WorkspaceViewModel : ViewModelBase { ... }
并处理所有 MVVM 东西,如OnPropertyChanged
处理程序等。在MainWindowViewModel
调用层次结构中,将资源文件加载到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;
}
请注意,从这些方法返回的数据很好。这些方法本身似乎不会导致上述问题 - 但是上下文切换可能是。我在这里真的很茫然,所以欢迎任何想法。