После прочтения некоторых ваших комментариев, я думаю, что у меня есть лучшее понимание сценария.Вот что вам нужно сделать.
Во-первых, убедитесь, что одна из ваших ViewModels имеет ссылку на модель, которая должна открывать и закрывать окно.Один из способов сделать это - внедрение зависимости от конструктора.
public ViewModel(Model model) // or IModel
{
...
Далее вам нужно захватить диспетчер пользовательского интерфейса в этом ViewModel.Лучшее место для этого, вероятно, также конструктор ViewModel.
private Dispatcher dispatcher;
public ViewModel(Model model)
{
dispatcher = Dispatcher.CurrentDispatcher;
...
Теперь создайте два события в вашей модели;один, чтобы открыть и один, чтобы закрыть окно.
class Model
{
internal event Action OpenWindow = delegate { };
internal event Action CloseWindow = delegate { };
...
И подписаться на них в конструкторе ViewModel.
public ViewModel(Model model)
{
dispatcher = Dispatcher.CurrentDispatcher;
model.OpenWindow += OnWindowOpen;
model.CloseWindow += OnWindowClose;
...
}
Теперь откройте и закройте окно с помощью диспетчера пользовательского интерфейса в ViewModelclass;
private Window window;
private void OnWindowOpen()
{
// still on background thread here
dispatcher.BeginInvoke(new ThreadStart(() =>
{
// now we're on the UI thread
window = new Window();
window.Show();
}
}
private void OnWindowClose()
{
dispatcher.BeginInvoke(new ThreadStart(() =>
{
window.Close();
}
}
Наконец, вызовите события OpenWindow и CloseWindow из вашего фонового потока в вашей модели так же, как вы вызываете любое событие.Ваша модель может выглядеть примерно так:
class Model
{
private Thread worker;
internal event Action OpenWindow = delegate { };
internal event Action CloseWindow = delegate { };
public Model()
{
worker = new Thread(Work);
worker.Start();
}
private void Work()
{
while(true)
{
if (/*whatever*/) OpenWindow();
else if (/*whatever*/) CloseWindow();
}
}
}