![](/img/trans.png)
[英]Background STA thread with custom window style using window chrome throwing cross threaded access exception
[英]Displaying Window from STA Thread using ShowDialog()
我需要从dll项目中打开一个窗口(在后台运行或在调用时触发)。 为此,我需要使用标记为[STAThread]的方法打开一个窗口以创建该窗口的实例。
我正在使用MVVM模式将ViewModel绑定到视图,并且该视图作为用户控件添加到MainWindow。
在“视图”上,有一个按钮绑定到“关闭”窗口的命令。 ViewModel中的命令调用CloseCommand(),后者又将调用window.Close()方法。
代码段:
MethodShowingTheWindow() {
var idVM = new IDWindowViewModel();
ShowForm<MainWindow>(idVM); // Works fine, Close Command closes the window.
ShowForm<MainWindow>(idVM); // hits the ShowDialog() line, then just jumps to the while loop
ShowForm<MainWindow>(idVM); // waiting for the thread to finish. Never displays the window.
ShowForm<MainWindow>(idVM);
}
[STAThread]
public void ShowForm<T>(IViewModel vm) {
Thread th = new Thread(new ThreadStart(delegate {
var window = new MainWindow();
window.DataContext = vm;
vm.CloseAction = new Action(() => window.Close()); // Does this when the Close Action is called from the viewmodel (Close the window).
try {
window.ShowDialog();
} catch (Exception ex) {
throw ex;
}
}));
th.ApartmentState = ApartmentState.STA;
th.Start();
while (th.IsAlive) {
//Wait for thread to finish
}
}
我只需要知道为什么窗口不会在第二次ShowWindow(idVM)调用中出现? 我能想到的是,窗口没有正确关闭/处理。 我尝试将以下内容添加到CloseAction操作中:
...
vm.CloseAction = new Action(() => {
if (window is IDisposable) (window as IDisposable).Dispose();
window.Close();
});
但是(窗口是IDisposable)==假?
任何帮助将不胜感激。
这是我为您设计的方案。 使用分派器以避免STA异常:
async Task MethodShowingTheWindow()
{
var idVM = new IDWindowViewModel();
await ShowForm<MainWindow>(idVM); // Works fine, Close Command closes the window.
await ShowForm<MainWindow>(idVM); // hits the ShowDialog() line, then just jumps to the while loop
await ShowForm<MainWindow>(idVM); // waiting for the thread to finish. Never displays the window.
await ShowForm<MainWindow>(idVM);
}
public await Task ShowForm<T>(IViewModel vm)
{
Dispatcher.InvokeAsync(() =>
{
var window = new MainWindow();
window.DataContext = vm;
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
vm.CloseAction = new Action(() => window.Close());
});
window.ShowDialog();
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.