Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Opening new window in MVVM WPF

Tags:

c#

mvvm

wpf

I have a Button and I bind this button to a command in ViewModel say OpenWindowCommand. When I click on the button I want to open a new window. But creating a window instance and showing a window from view model is a violation of MVVM. I have created interface like

interface IWindowService {     void showWindow(object dataContext); } 

and WindowService implements this interface like

class WindowService : IWindowService {     public void showWindow(object dataContext)     {         ChildWindow window=new ChildWindow();         window.DataContext=dataContext;         window.Show();     } } 

In this class I have specified ChildWindow. So this class is tightly coupled with showing ChildWindow. When I want to show another window, I have to implement another class with the same interface and logic. How can I make this class generic so that I can just pass an instance of any window and the class will be able to open any window?

I am not using any built MVVM frameworks. I have read many articles on StackOverflow but I could not found any solution for this.

like image 956
DT sawant Avatar asked Sep 15 '14 10:09

DT sawant


People also ask

How do you navigate from one XAML page to another in WPF MVVM?

To package content for navigation, WPF provides the Page class. You can navigate from one Page to another declaratively, by using a Hyperlink, or programmatically, by using the NavigationService. WPF uses the journal to remember pages that have been navigated from and to navigate back to them.

Do I have to use MVVM in WPF?

For trivial projects MVVM is unnecessary. Using only the View is sufficient. For simple projects, the ViewModel/Model split may be unnecessary, and just using a Model and a View is good enough. Model and ViewModel do not need to exist from the start and can be introduced when they are needed.

How does WPF MVVM work?

The single most important aspect of WPF that makes MVVM a great pattern to use is the data binding infrastructure. By binding properties of a view to a ViewModel, you get loose coupling between the two and entirely remove the need for writing code in a ViewModel that directly updates a view.


1 Answers

You say "creating window instance and showing window from view model is violation of MVVM". This is correct.

You are now trying to create an interface that takes a type of view specified by the VM. This is just as much of a violation. You may have abstracted away the creation logic behind an interface, but you are still requesting view creations from within the VM.

VM's should only care about creating VM's. If you really need a new window to host the new VM, then provide an interface as you have done, but one that does NOT take a view. Why do you need the view? Most (VM first) MVVM projects use implicit datatemplates to associate a view with a particular VM. The VM knows nothing about them.

Like this:

class WindowService:IWindowService {     public void ShowWindow(object viewModel)     {         var win = new Window();         win.Content = viewModel;         win.Show();     } } 

Obviously you need to make sure you have your VM->View implicit templates set up in app.xaml for this to work. This is just standard VM first MVVM.

eg:

<Application x:Class="My.App"              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"              xmlns:vm="clr-namespace:My.App.ViewModels"              xmlns:vw="clr-namespace:My.App.Views"              StartupUri="MainWindow.xaml">     <Application.Resources>          <DataTemplate DataType="{x:Type vm:MyVM}">             <vw:MyView/>         </DataTemplate>      </Application.Resources> </Application> 
like image 75
GazTheDestroyer Avatar answered Sep 18 '22 02:09

GazTheDestroyer