Eric
Eric

Reputation: 2059

Using M-V-VM with WPF, how do I instantiate a Dialog View given a ViewModel?

I'm using M-V-VM with dialog boxes. The process I'm using for creating dialogs is as follows:

I have this all working. However, currently my solution for DialogProvider is to use reflection to manually find the View class to instantiate based on the name of the ViewModel, like so:

var viewModelType = viewModel.GetType();
var dialogTypeName = Regex.Replace(viewModelType.Name, "ViewModel$", "Dialog");
var viewType = Assembly.GetExecutingAssembly().GetType(dialogTypeName);
if (viewType == null)
    throw new InvalidOperationException("Could not find view for given type.");

var dialog = (Dialog)viewType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]);
dialog.DataContext = viewModel;
dialog.Owner = Application.Current.MainWindow;

return dialog;

This is suboptimal, as the View must be named the same as the ViewModel, and must be in the same namespace, etc.

Ideally I would use the DataTemplate machinery to do this. What I would like to do is the same as using a DataTemplate for a view, and using a ContentPresenter to choose the view based on the DataTemplate's DataType attribute (see Josh Smith's MVVM article. However, I need to do this in C# code (within the DialogProvider).

Is this possible? I'm imagining things like creating a ContentPresenter in C#, settings it's DataTemplate, and then reaching it to pull the Dialog view out???

Eric

Upvotes: 3

Views: 1035

Answers (2)

jbe
jbe

Reputation: 7031

We use dependency injection (DI) to get the View (or Dialog) for the specified ViewModel. This approach let us to unit test the ViewModels with a MockView.

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564641

Why not just have the DialogProvider use a default View that is nothing but a Window containing a ContentPresenter.

You could then merge the window resources with your current window resources (this would let a DataTemplate for your new ViewModel map to the appropriate View, defined as a UserControl).

Once you've done that, all you'd have to do is set the content of the ContentPresenter to your DialogViewModel from C#, and WPF would handle mapping the approriate View into place.

Upvotes: 3

Related Questions