Доступ к окну GUI, созданному Caliburn.Микро-приложение в фоновом потоке?

#c# #wpf #multithreading #mvvm #caliburn.micro

#c# #wpf #многопоточность #mvvm #caliburn.micro

Вопрос:

У меня есть приложение caliburn.micro WPF, и я запускаю его из F # с помощью вызова этой функции:

             public void LaunchGUI()
            {
                if (_guiWindow == null)
                {
                    var windowThread = new Thread(() =>
                    {
                        try
                        {
                            // Create our context, and install it:
                            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));

                            AppBootstrapper.Initialize();
                            var app = new App();
                            app.InitializeComponent();


                            //guiWindow = app.MainWindow;
                            //// When the window closes, shut down the dispatcher
                            //guiWindow.Closed  = (s, e) =>
                            //    Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
                            //guiWindow.Closed  = (s, e) =>
                            //    guiWindow = null;
                            //guiWindow.WindowState = WindowState.Minimized;
                            //guiWindow.Show();
                            //guiWindow.WindowState = WindowState.Normal;
                            //guiWindow.Activate();
                            // Start the Dispatcher Processing
                            Dispatcher.Run();
                        }
                        catch (Exception e)
                        {
                            LogMessage("error in gui thread: "   e);
                            //guiWindow.Close();
                            //guiWindow = null;
                        }

                    });
                    windowThread.SetApartmentState(ApartmentState.STA);
                    windowThread.IsBackground = true;
                    windowThread.Start();
                }
                else
                {
                    _guiWindow.WindowState = WindowState.Minimized;
                    _guiWindow.Show();
                    _guiWindow.WindowState = WindowState.Normal;
                    _guiWindow.Activate();
                }
            }
        }
  

Проблема в том, что мне нужно иметь ссылку на главное окно, чтобы я мог отслеживать, открыто ли оно все еще и т.д., Но оно всегда равно null (отсюда и прокомментированный код). Обратите внимание, что это отлично работает при запуске «обычного» приложения MVVM и инициализации его аналогичным образом:

     public void ShowGui()
    {
        if (guiWindow == null)
        {
            var windowThread = new Thread(() =>
            {
                try
                {
                    // Create our context, and install it:
                    SynchronizationContext.SetSynchronizationContext(
                        new DispatcherSynchronizationContext(
                            Dispatcher.CurrentDispatcher));

                    guiWindow = new MainWindow();
                    // When the window closes, shut down the dispatcher
                    guiWindow.Closed  = (s, e) =>
                        Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
                    guiWindow.Closed  = (s, e) =>
                        guiWindow = null;
                    guiWindow.WindowState = WindowState.Minimized;
                    guiWindow.Show();
                    guiWindow.WindowState = WindowState.Normal;
                    guiWindow.Activate();

                    // Start the Dispatcher Processing
                    Dispatcher.Run();
                }
                catch (Exception)
                {
                    try
                    {
                        guiWindow.Close();
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                    guiWindow = null;
                }

            });
            windowThread.SetApartmentState(ApartmentState.STA);
            windowThread.IsBackground = true;
            windowThread.Start();
        }
        else
        {
            guiWindow.WindowState = WindowState.Minimized;
            guiWindow.Show();
            guiWindow.WindowState = WindowState.Normal;
            guiWindow.Activate();
        }
    }
  

Мой вопрос в том, как мне получить доступ к созданному главному окну?

Ответ №1:

// вы получаете основные окна приложения следующим образом:

var _guiWindow = Приложение.Текущий.MainWindow как MainWindow;

Комментарии:

1. Это всегда значение null, независимо от того, пытаюсь ли я получить к нему доступ из основного потока или из потока GUI, который я создал здесь.

2. Неважно, похоже, что это была проблема с потоками (потребовалось немного подождать, пока оно будет инициализировано). Теперь у меня возникла проблема с попыткой получить доступ к нему из другого потока, но это уже другая тема. Спасибо.