我有一个窗口1,其中点击按钮我在新线程中打开窗口2。 以下是我的代码
private void Button_Click_2(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(() =>
{
Scanner w = new Scanner();
w.Show();
w.Closed += (sender2, e2) =>
w.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
窗口2有表格我在按钮上点击
获取表格值 private void EnterProduct(object sender, RoutedEventArgs e)
{
var data = ProductDetailsData;
LoadCurrentBetween objMain = new LoadCurrentBetween(); //new MainWindow();
objMain.fillorderform(data);
}
在按钮上单击窗口2我将表单的值传递给另一个视图
public void fillorderform(dynamic data)
{
this.Dispatcher.Invoke(() =>
{
LoadCurrentdetails.Part = data.Part;
LoadCurrentBetween loadCurrentbtw = new LoadCurrentBetween();
Switcher.Switch(loadCurrentbtw);
});
} public static class Switcher
{
public static MainWindow pageSwitcher;
public static void Switch(UserControl newPage)
{
pageSwitcher.Navigate(newPage);
}
}
以下代码在" this.Content = nextPage;"
给出错误调用线程无法访问此对象,因为另一个线程拥有它。
public void Navigate(UserControl nextPage)
{
this.Dispatcher.Invoke(() =>
{
var aa = nextPage.Dispatcher.CheckAccess();
this.Content = nextPage;
});
}
我见过其他开发者提出的类似问题,但我没有得到如何修复。 请帮忙
答案 0 :(得分:1)
WPF非常严格(与Windows窗体相比),要求更新UI元素的方法在主/ UI线程上完成。所以你肯定希望两个窗口都在主/ UI线程中。你看到的错误是如果你尝试从另一个线程在WPF中进行UI工作会发生什么,所以你绝对不得不停止这样做。可以在同一个UI线程上打开多个窗口。
如果你的某个窗口正在进行重量级处理以使UI锁定,那么最简单的事情可能是将async关键字添加到按钮单击事件中,并将正在执行的工作放在另一个具有异步的方法中关键词。然后,当您调用helper方法时,使用await关键字。
我同意其他人的看法,BackgroundWorker和Task是另外两种在后台线程中完成重量级处理的方法,同时还具有响应式UI。任务比BackgroundWorker更容易使用。
如果您使用的是BackgroundWorker,则使用RunWorkerCompleted事件可能已经足够了。如果是这样,请看这篇文章:How to use WPF Background Worker。如果您正在使用BackgroundWorker,并且需要从后台线程调用UI类中的自定义方法,则将窗口/对话框的Dispatcher对象传递给后台线程(或以其他方式访问它),以及何时它需要回调到UI,使用Invoke和Dispatcher对象。通过使用Invoke,您从后台线程调用的方法将在UI线程上执行。