0

I'm working on a simple project to learn Caliburn.Micro

I got two ViewModels SettingsViewModel and MainViewModel. I want to show the MainViewModel and immediatelly after show the SettingsViewModel as a modal Dialog, so the User can configure the application before it starts.

When i start my App the View for MainViewModel doesn't show but the modal pops up. When i close the Dialog with TryClose(true) in Start(), my Application will exit. I want only SettingsViewModel to close, so that i can continue with Handle(Settings message) in MainViewModel

AppBootstrapper:

protected override void OnStartup(object sender, StartupEventArgs e)
{
     DisplayRootViewFor<MainViewModel>();
}

SettingsViewModel:

using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AbrechnungPSA.ViewModels
{
    class SettingsViewModel : Screen
    {
        private IEventAggregator _eventAggregator;

        public SettingsViewModel(IEventAggregator eventAggregator)
        {  
            _eventAggregator = eventAggregator;
        }

        /// <summary>
        /// Starts the Main Application
        /// </summary>
        public void Start()
        {
            TryClose(true); 

            _eventAggregator.PublishOnUIThread(new Settings());           
        }
    }
}

MainViewModel:

using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace AbrechnungPSA.ViewModels
{
    public class MainViewModel : PropertyChangedBase, IHandle<Settings>
    {
        private Settings _settings;

        private readonly IEventAggregator _eventAggregator;
        private readonly IWindowManager _windowManager;

        public MainViewModel(IEventAggregator eventAggregator, IWindowManager windowManager)
        {
            _eventAggregator = eventAggregator;
            _eventAggregator.Subscribe(this);

            _windowManager = windowManager;

            dynamic settings = new ExpandoObject();
            settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            settings.ResizeMode = ResizeMode.NoResize;

            var result = _windowManager.ShowDialog(new SettingsViewModel(_eventAggregator), null, settings);
        }

        /// <summary>
        /// Receive User adjusted Settings and start Application
        /// </summary>
        /// <param name="message"></param>
        public void Handle(Settings message)
        {
            _settings = message;

            // Continue here ...
        }
    }
}
steschwa
  • 95
  • 3
  • 8

1 Answers1

1

The ShowDialog method won't return until the settings dialog has been closed.

Display the settings dialog in the OnStartup method:

Bootstrapper:

protected override void OnStartup(object sender, StartupEventArgs e)
{
    base.OnStartup(sender, e);
    DisplayRootViewFor<MainViewModel>();

    dynamic settings = new ExpandoObject();
    settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
    settings.ResizeMode = ResizeMode.NoResize;

    var settingsVm = new SettingsViewModel(_container.GetInstance<IEventAggregator>());
    var result = _container.GetInstance<IWindowManager>()
        .ShowDialog(settingsVm, null, settings);

    settingsVm.Start();
}

MainViewModel:

class MainViewModel : PropertyChangedBase, IHandle<Settings>
{
    private Settings _settings;

    private readonly IEventAggregator _eventAggregator;
    private readonly IWindowManager _windowManager;

    public MainViewModel(IEventAggregator eventAggregator, IWindowManager windowManager)
    {
        _eventAggregator = eventAggregator;
        _eventAggregator.Subscribe(this);
        _windowManager = windowManager;
    }

    public void Handle(Settings message)
    {
        _settings = message;
        // Continue here ...
    }
}
mm8
  • 163,881
  • 10
  • 57
  • 88