Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Opening a new window on button click WPF MVVM

Tags:

c#

mvvm

wpf

xaml

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.

like image 806
whitefang1993 Avatar asked May 18 '16 08:05

whitefang1993


People also ask

How do you open a new window when a button is clicked in WPF?

To add a new Window to your project: Right Click on your Project --> Add --> New Element --> Window. Name it as you please, I will use the default (Window1). Now you can modify this window in the same way as you did for your original window.

Do I have to use MVVM in WPF?

The Windows Presentation Framework (WPF) takes full advantage of the Model-View-ViewModel (MVVM) pattern. Though it is possible to create WPF applications without using the MVVM pattern, a little investment in learning can make building WPF applications much simpler.

What is MVVM command?

Commands are an implementation of the ICommand interface that is part of the . NET Framework. This interface is used a lot in MVVM applications, but it is useful not only in XAML-based apps.

What is MVVM pattern in WPF?

MVVM pattern has three separate layers of abstraction. Model: Model is mostly the database entities that represent the row data for the application. For Windows, application model is the entity class, which contains properties. View: For WPF applications view is the XAML based user interface.


1 Answers

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.

like image 193
StepUp Avatar answered Sep 18 '22 10:09

StepUp