Search code examples
c#wpfmvvmfolderbrowserdialog

BrowseFolderDialog - Does this break MVVM?


I am creating an WPF following MVVM. In this I have a button that I would like to Open a FolderBrowserDialog so a user can select a folder path. I know opening dialog is something widely discussed in terms of MVVM because .ShowDialog from the view Model is anti-pattern. So after some research I found this post and answer How to use a FolderBrowserDialog from a WPF application with MVVM where the accepted answer suggests doing:

var dlg = new FolderBrowserDialog();
DialogResult result = dlg.ShowDialog();

Does this break MVVM? If so whats an alternative that doesn't rely on frameworks such as Prism?


Solution

  • With MVVM, what's considered a pattern vs. an anti-pattern is highly subjective and often equates to religious dogma.

    MVVM is a great pattern because it helps you separate concerns, allows you to more easily test your code, and opens up the possibility of easily changing your UI in the future.

    How you handle the FolderBrowserDialog and other things similar to it, depend on your app and your particular needs.

    If your app is small, or you're only calling the dialog once, or you're not unit testing your view-model, then just call the FolderBrowserDialog from your view-model and be done with it.

    However, if strict separation of concerns is important to you and your app, then consider creating a service class to handle folder dialog work that you can call from your app's view-model.

    Service Class

    This is a simple public class that gives your app's view-models an API to open a FolderBrowserDialog. Here is a super-simple example:

    public class FolderBrowserDialogService
    {
        public FolderBrowserResponse ShowFolderBrowserDialog()
        {
            var dialog = new FolderBrowserDialog();
            var result = dialog.ShowDialog();
            
            // TODO: Convert result to FolderBrowserResponse
            // FolderBrowserResponse is a custom type you create so your view-model
            // doesn't know about DialogResult
    
            return folderBrowserResponse;
        }
    }
    

    Then, in your app's view-model, you can call the service class like so:

    var service = new FolderBrowserDialogService();
    var result = service.ShowFolderBrowserDialog();
    
    //TODO: Process the result...
    
    

    I hope this gives you some ideas.