4

I'm very much new in WPF & MVVM paradigm and i'm trying hard to absorb it. The problem i'm having looks like a lot of MVVM beginers face the same & it seems there's no simple approach. So, to keep the problem domain simple here's just an experimental work.

I have a MainWindow with a "New" button on it. I want to show an instance of a NewWindow.xaml when i click on this button. How can i do this from MainWindowViewModel? Can mediator pattern help? Please suggest any good implementation reference.

I also have a "Close" button on the MainWindow & i want to exit the application when i click this one. And I need help again :(

atiyar
  • 7,762
  • 6
  • 34
  • 75

2 Answers2

2

i did have the same problem a while ago.

at least i use a very simple approach and i'm happy with. here is my solution.

in your viewmodel you just have to write one line of code:

var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", newdialogwindowVMgoeshere);
//do what you want with the dialogresult
Community
  • 1
  • 1
blindmeis
  • 22,175
  • 7
  • 55
  • 74
1

I put dialog code into the View's CodeBehind. I still route the command through the ViewModel, but the ViewModel calls the View's implementation and gets the result.

Suppose I have MainWindow View (xaml), and a MainWindow ViewModel and I want to save a file.

In the codebehind View (MainWindow.xaml.cs) I add the code to create the dialog and return the save filename:

    public FileInfo OpenSaveFileDialog(string title, string filter)
    {
        var dialog = new SaveFileDialog
        {
            Filter = filter,
            Title = title
        };

        var result = dialog.ShowDialog();
        if (!result.Value) return null;

        return new FileInfo(dialog.FileName);
    }

In the ViewModel I have a DoSaveFile() method:

    public void DoSaveFile()
    {
        var file = OpenSaveFileDialog("Save File", "Super files (*.super)|*.super |All files (*.*)|*.*");
        if (file == null) return;
        //Save logic...
     }

    public DelegateCommand SaveFile { get { return Get("SaveFile", new DelegateCommand(DoSaveFile, () => true)); } }

In the MainWindow.xaml I have a button bound to to the delegate command:

    <Button Content="Save File" Command="{Binding SaveFile}"/>

Like MVP, this implementation is chatty, but it works really well for test and separation of concerns. To me, it makes sense to leave the mechanics of window opening to the View class, even thought it feels a bit like an active-view.

Ritch Melton
  • 11,498
  • 4
  • 41
  • 54
  • 1
    How does the ViewModel have a reference to the view so as to call the public member (OpenSaveFileDialog) in the View Instance? – Ralph Shillington Mar 08 '11 at 13:17
  • i think the viewmodel will get something like an IView interface as constructor parameter. the View of course implement IView and get passed to the viewmodel as IView – blindmeis Mar 08 '11 at 13:51
  • I am also seeking for a good pattern to show another window from ViewModel. But I think your solution is not good. ViewModel should not know anything about View. It is better if ViewModel expose an event, and View handles it for showing new window. – Ha Pham Mar 31 '17 at 13:54