【发布时间】:2016-03-04 03:40:40
【问题描述】:
我是 wpf 和多线程的新手。我有五个 UserControl,A-B-C-D-E 并返回 A
我正在尝试在加载 B 时重新加载 userControl A。
public class Main{
public List<Page> pages;
public UserControl currentScreen;
}
public class Page
{
public UserControl userControl;
public String xamlUrl;
public void Invalidate()
{
try{
var th = new Thread(() =>
{
ParseUserControl(xamlUrl);
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
}
void ParseUserControl(String xamlUrl)
{
Console.WriteLine("ParseUserControl" + Thread.CurrentThread.ManagedThreadId);
string strXaml = System.IO.File.ReadAllText(xamlUrl);
UserControl uc = (UserControl)System.Windows.Markup.XamlReader.Parse(strXaml);
UserControlParsedEventArgs args = new UserControlParsedEventArgs(uc);
Application.Current.Dispatcher.Invoke(() => UserControlParsed(args));
}
void UserControlParsed(UserControlParsedEventArgs e)
{
Console.WriteLine("UserControlParsed " + Thread.CurrentThread.ManagedThreadId);
userControl= e.userControl;
Main.getInstance().currentScreen = userControl; //this line here throws error
}
}
主要思想是让一个线程解析用户控件,并在加载用户控件后,将其发送回主屏幕进行显示。
但是,我收到此错误:“调用线程无法访问此对象,因为不同的线程拥有它。”
我认为这是因为 UserControl 是在不同的线程中创建的,但我已经做了 UserControl uc = e.userControl。
我已经检查了线程 ID:
main is running on id 8 <----------------------
ParseUserControl is running on id 9 |---always same
UserControlParsed is running on id 8 <---------
所以 UserControlParsed 中的 UserControl 属于线程 8,据说可以在 main 中使用?我很困惑。
【问题讨论】:
-
通常,其他线程不会创建 UI 元素,而只是准备好数据。但即便如此,如果数据没有正确编组,数据也不能简单地绑定到 Gui 线程,这意味着数据必须与主窗口位于同一线程上。有很多不同的方法可以确保数据在主窗口线程上,您可以在谷歌搜索。
-
如果您使用正确的数据绑定(无论如何您都应该这样做,而不是在代码隐藏中创建 ui 元素),那么您可以在您喜欢的任何线程中创建视图模型,并且 ui 会自行更新自动。
标签: c# wpf multithreading xaml user-controls