tags:

views:

2538

answers:

3

Ok I really would like to know how expert MVVM developers handle an openfile dialog in WPF.

I don't really want to do this in my ViewModel(where 'Browse' is referenced via a DelegateCommand)

    void Browse(object param)
    {
        //Add code here
        OpenFileDialog d = new OpenFileDialog();


        if (d.ShowDialog() == true)
        {
            //Do stuff
        }
    }

Because I believe that goes against MVVM methodology.

What do I do?

+6  A: 

The best thing to do here is use a service.

A service is just a class that you access from a central repository of services, often an IOC container. The service then implements what you need like the OpenFileDialog.

So, assuming you have an IFileDialogService in a Unity container, you could do...

void Browse(object param)
{
    var fileDialogService = container.Resolve<IFileDialogService>();

    string path = fileDialogService.OpenFileDialog();

    if (!string.IsNullOrEmpty(path))
    {
        //Do stuff
    }
}
Cameron MacFarland
+1  A: 

I use a service which i for example can pass into the constructor of my viewModel or resolve via dependency injection. e.g.

public interface IOpenFileService
{
    string FileName { get; }
    bool OpenFileDialog()
}

and a class implementing it, using OpenFileDialog under the hood. In the viewModel, i only use the interface and thus can mock/replace it if needed.

Botz3000
My only problem with instance properties on services is what about if two threads call OpenFileDialog at the same time? Not really an issue for file dialogs but can be an issue for other types of services.
Cameron MacFarland
With dependency injection containers, you can usually register it so that each time the service is resolved, a new instance is created. So you could create a new service, use it and throw it away after that. Or, you only use the OpenFileDialog() method and let it return a string, or null if it was aborted.
Botz3000
While this is true, I agree with Cameron's assessment here. You run the risk of unintended side-effects with the property approach. I know that this is the same pattern that the .NET Framework uses, but this isn't necessarily an argument for this pattern, just that it exists. I prefer the use of checking for null in the return value to indicate a failure of some sort (or user hitting "Cancel").
Anderson Imes
A: 

Having a service is like opening up a view from viewmodel. I have a Dependency property in view, and on the chnage of the property, I open up FileDialog and read the path, update the property and consequently the bound property of the VM

Jilt