How to manage multiple windows in MVVM

I know that there are several questions like this, but I could not find a definitive answer. I'm trying to dive into MVVM and keep everything as clean as possible, but not sure how to start / close windows, sticking to the template.

My initial thinking was with the commands tied to the ViewModel launch code to launch a new view, with the DataContext, and then set the ViewModel for it via XAML. But this violates pure MVVM, I think ...

After some answers to the search in googling / reading, I came across a concept WindowManager(for example, in CaliburnMicro), now, if I were to implement one of them in the MVVM project with vanilla, is this in my ViewModels? or just at the heart of my application? I am currently separating a project from an assembly / project project Model, assembly / project, ViewModeland assembly / project View. Should this go to another, "sound" assembly?

Which leads a bit to my next question (to some extent related to the above), how do I run the application in terms of MVVM? Initially, I ran my MainView.xaml from App.xaml, and the DataContext in XAML attached the assigned ViewModel. If I add WindowManager, is this the first thing my application launches? Am I doing this from the code behind App.xaml.cs?

+4
source share
1 answer

Well, basically it depends on how your application looks (that is, how many windows are open at the same time, modal windows or not ... etc.).

The general recommendation that I would give is not to try to make a “clean” MVVM; I often read things like "there must be a ZERO code" ... etc., I do not agree.

Currently, I am separating my project from the assembly / project of the model, ViewModel assembly / project and view assembly / project. If this happens in another, "Core" assembly?

ViewModels - , , -, Model. .

ViewModel , , . , WCF- .

"Core" (IMHO), , , (, ... ..).

( ... ..), , . ViewModels . ViewModels, , , .

, MainWindow, , :

// Main viewModel
public MainViewModel : ViewModelBase
{
    ...
    // EventArgs<T> inherits from EventArgs and contains a EventArgsData property containing the T instance
    public event EventHandler<EventArgs<MyPopupViewModel>> ConfirmationRequested;
    ...
    // Called when ICommand is executed thanks to RelayCommands
    public void DoSomething()
    {
        if (this.ConfirmationRequested != null)
        {
            var vm = new MyPopupViewModel
            {
                // Initializes property of "child" viewmodel depending
                // on the current viewModel state
            };
            this.ConfirmationRequested(this, new EventArgs<MyPopupViewModel>(vm));
        }
    }
}
...
// Main View
public partial class MainWindow : Window
{
    public public MainWindow()
    {
        this.InitializeComponent();

        // Instantiates the viewModel here
        this.ViewModel = new MainViewModel();

        // Attaches event handlers
        this.ViewModel.ConfirmationRequested += (sender, e) =>
        {
            // Shows the child Window here
            // Pass the viewModel in the constructor of the Window
            var myPopup = new PopupWindow(e.EventArgsData);
            myPopup.Show();         
        };
    }

    public MainViewModel ViewModel { get; private set; }
}

// App.xaml, starts MainWindow by setting the StartupUri
<Application x:Class="XXX.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             ...
             StartupUri="Views/MainWindow.xaml">
+2

Source: https://habr.com/ru/post/1526917/


All Articles