I'm using M-V-VM with dialog boxes. The process I'm using for creating dialogs is as follows:
- A ViewModel command wishes to open a dialog.
- It creates the ViewModel for the dialog (we'll call it DialogViewModel).
- It then passes the ViewModel off to a DialogProvider to create the actual View. This makes my dialog boxes testable, as the provider can provide either a the real view or a test view.
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 DataTe开发者_StackOverflowmplate'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
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.
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.
精彩评论