Opening a new window on button click WPF MVVM

16,837

Solution 1

You can create a separate service for launching views as dialog so that it can be used in a generic way across the application. And will inject this service to the ViewModel via Constructor which wants to launch any dialog.

public interface IDialogWindowService<T>
{
    void Show();
    void ShowDialog();
}

public class DialogWindowService<T> : IDialogWindowService<T> where T : Window
{
    public void Show()
    {
        container.Resolve<T>().Show();
    }

    public void ShowDialog()
    {
        container.Resolve<T>().ShowDialog();
    }
}

Now just inject this service to the respective ViewModel.

public class YourViewModel
{
    //commands
    public ICommand someCommand { get; set; }

    private IDialogWindowService<BookingView> _dialogService;
    public YourViewModel(IDialogWindowService<YourView > dialogService)
    {
        _dialogService = dialogService
        someCommand = new RelayCommand(someCommandDoJob, () => true);
    }

    public void someCommandDoJob(object obj)
    {
        //Since you want to launch this view as dialog you can set its datacontext in its own constructor.    
        _dialogService.ShowDialog();
    }
}

OR

you can use DataTemplates to change view. It allows to dynamically switch Views depending on the ViewModel:

<Window>
   <Window.Resources>
      <DataTemplate DataType="{x:Type ViewModelA}">
         <localControls:ViewAUserControl/>
      </DataTemplate>
      <DataTemplate DataType="{x:Type ViewModelB}">
         <localControls:ViewBUserControl/>
      </DataTemplate>
   <Window.Resources>
  <ContentPresenter Content="{Binding CurrentView}"/>
</Window>

If Window.DataContext is an instance of ViewModelA, then ViewA will be displayed and

Window.DataContext is an instance of ViewModelB, then ViewB will be displayed.

The best example I've ever seen and read it is made by Rachel Lim. See the example.

Solution 2

Depending on your usage, there isn't anything wrong with opening a view from the view's code-behind. It's still view code after all.

MyView view = new MyView();
view.Show();

Otherwise, if you need to open a window from the ViewModel or using a ICommand, then you can look at the "Open Windows and Dialogs in MVVM" library I wrote on GitHub. This will demonstrate how to open a Window by clicking on a button using the MVVM design pattern.

Share:
16,837
whitefang1993
Author by

whitefang1993

Updated on June 16, 2022

Comments

  • whitefang1993
    whitefang1993 almost 2 years

    I am learning WPF MVVM and want to open a new window on a button click from a main window.

    I know each View has to have an equivalent ViewModel and one of the basic principles of MVVM is that the ViewModel must not know anything about the View.

    So please can anybody provide me a simple clean example that does not violate any MVVM principles on how to create two Views and two ViewModels that have the following functionality:

    Show a new view by clicking a button from a main View.