我有一个TabConrol
,当用户执行某些操作时,会以编程方式添加新的TabItem
。在此选项卡中,有一个框架将包含所需的Page.XAML
。这一切都像这样完美;
private void addNewTab()
{
TabItem tab = new TabItem();
Grid g = new Grid();
Frame f = newFrame();
g.Children.Add(f);
tab.Content = g;
MyTabControl.Items.Add(tab);
MyTabControl.SelectedItem = tab;
}
private Frame newFrame()
{
Frame f = new Frame();
//Full logic for Frame removed
f.Navigate(new MyPage());
return f;
}
问题有时候加载新的Frame
可能需要一段时间。所以我想做这个异步。因此,当它加载时,可能会有一个加载动画。我认为这样可行;
private async void addNewTab()
{
TabItem tab = new TabItem();
Grid g = new Grid();
var test = Task<Frame>.Factory.StartNew(() => newFrame(selectTab, value));
await test;
f = test.Result;
g.Children.Add(f);
tab.Content = g;
MyTabControl.Items.Add(tab);
MyTabControl.SelectedItem = tab;
}
private Frame newFrame()
{
Frame f = new Frame();
//Full logic for Frame removed
f.Navigate(new MyPage());
return f;
}
问题是它在运行时Frame f = new Frame();
的{{1}}上返回了跟随错误;
发生了'System.InvalidOperationException'类型的异常 PresentationCore.dll但未在用户代码中处理
附加信息:调用线程必须是STA,因为很多 UI组件需要这个。
开始认为我试图以错误的方式解决这个问题。处理这个问题的最佳方法是什么?
答案 0 :(得分:4)
构建任何合理的UI都是一项非常快速的操作。但是,确定要在该UI中显示的数据可能需要任何时间。所以我认为这实际上很慢。
您无法在后台线程上构建实际的UI组件;那个异常告诉你的是什么。
但您可以在后台线程上构建数据,然后将加载到UI中:
private async Task addNewTabAsync()
{
TabItem tab = new TabItem();
Grid g = new Grid();
var data = await Task.Run(() => getData(value));
Frame f = new Frame();
// Fill out frame with data.
f.Navigate(new MyPage());
g.Children.Add(f);
tab.Content = g;
MyTabControl.Items.Add(tab);
MyTabControl.SelectedItem = tab;
}
请注意,我将async void
更改为async Task
(并添加了Async
后缀),并将StartNew
更改为Run
以遵循最佳做法。