簡體   English   中英

使用ShowDialog()從STA線程顯示窗口

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM