简体   繁体   中英

WPF open seperate windows in MVVM

I am new in WPF and I am trying to keep the MVVM pattern.
I have a main form that it will presents some reports (in the form of tiles but it really doesn't matter).
So I want if the user double click one of the reports to open the report in a new seperate window.
What i did and I know that this is not the correct MVVM approach is that I have this command at the ReportsmanagerViewModel

Private Sub OpenReportExecute()
    Dim win As New ReportView
    win.Show()
End Sub

I don't use PRISM or any other framework. How can I open the window without breaking the MVVM?

MVVM should avoid referencing presentation assemblies from your view models. You need to call the new window from your view model, so how do you break the dependency?

The same way we break every dependency - an interface!

I usually call this an interaction service as a window is an interactivity object. There may be varying opinions on this. YMMV etc.

public interface IDataInteractionService
{
    //Implementations will display the data SOMEHOW
    void DisplayData(Data d);
}

And now the implementation

//Displayed data using windows!
public class WindowedDataInteractionService: IDataInteractionService
{
    public void DisplayData(Data d)
    {
        new Window().ShowDialog(); //basic implementation shows a window.
    }
}

The trick here is that your view model does not reference any WPF assemblies directly - this is called indirection . As a bonus, you have an interface so swapping the service implementation is possible with confidence that you wont break the view model code. This is an example of SOLID principles making life easier for future you.

You are not using PRISM or other Dependency Injection Framework , so a challenge for you will be getting the service to your view model. Common practice is to use a Singleton implementation to make your IDataInteractionService avaliable to the application.

Here is a example how you should do that, its in C# but you should have an Idea how to do it: Open a new Window in MVVM

Sorry for answering 2 times :) it was a mistake. The approach in this example is to Delegate the creation of that new Window in a FactoryClass which is responsible to create Windows Objects, set the DataContext to it and call method Show. With this you solve 2 Problems:

  1. Your ViewModel should not open other Windows, and Create other ViewModels

  2. You resolve Dependencies in your class. You place the creation of your Window in a Factory class.

This is important for UnitTesting your ViewModel. With much Dependencies it is harder to Test your ViewModel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM