As I mentioned before, I thought I was moving away from Web development. However, the dive into ASP.NET MVC that Silver Arcade brought about has roped me back in.
My work during the day (and some nights too) is still WPF though. I’ve discovered that MVC thinking has seeped into my WPF development.
Convention Over Configuration
A characteristic of most MVC frameworks is Convention Over Configuration. In short, it means that your “environment” makes assumptions about what you want and that you only need to be explicit about the exceptions.
A practical example of this is the way that the View for an Action is inferred from the name of the Controller and Action. After creating your Action, you create a folder for the controller and and view that matches the name of the action. It just works. If you need to make exception, you can.
An Example in WPF
In our WPF development we employ a number of Separated Presentation patterns. One of the more common patterns we use is MVP (in particular, the flavor of MVP implemented in Caliburn, which is really Supervising Controller).
Imagine a simple contact manager application. We can add new contacts, view a list of all contacts, and open individual contacts for viewing or editing. We can open as many individual contacts as we like.
Let’s say that there are buttons to open up the “Add New” view and “All Contacts” view. We can open an existing contact by double-clicking on them in the “All Contacts” view.
My solution setup for this imaginary (and highly contrived) application might look like this.
ApplicationPresenter would be the root object of my UI. It would have an ObservableCollection of IPresenter that would be bound to a TabControl in Shell.xaml. Likewise, ApplicationPresenter will have a CurrentPresenter of IPresenter that will be bound to the SelectedItem on the TabControl.
Shell.xaml is my only window in this example. All of the other views are user controls. I named it “shell” because I think of it as the outermost level of the views. Shell’s data context is set to ApplicationPresenter.
I’m not going to dive too much deeper into this, because I want to get to my real point.
My presenters don’t know anything about their views. It’s up to data binding to render each presenter with the correct view. This means that I need to create data templates for each of the presenters. Not such a big deal in a small application, but it can get tedious as the application grows.
Hmmm… This structure is beginning to look a lot like an MVC app. Perhaps I can have it automatically infer my data templates for me?
Yes we can. Here’s a very naiveté bit of code that will do just that. It makes some big assumptions:
- all of your presenters implement IPresenter
- all of your presenters are in a namespace containing “.Presenters”
- all of your views are in an analogous namespace containing in “.Views”
Again, this is not production ready code, just my spike to prove the idea works. Please feel free to make suggestions.
public static class MvpConfiguration
/// Creates a set of data templates pair to presenter classes based on naming conventions.
/// <remarks>If a data template is already present in the resources, then it is skipped.</remarks>
/// <param name="resources">The ResourceDictionary that the data templates for the views will be added to.</param>
public static void InferViewsFromPresenters(ResourceDictionary resources)
var lookup = MatchPresentersToViews();
foreach (var pair in lookup)
var template = CreateDataTemplate(pair.Value, pair.Key);
if (resources.Contains(template.DataTemplateKey)) continue;
private static Dictionary<Type, Type> MatchPresentersToViews()
var presenters = from type in Assembly.GetExecutingAssembly().GetTypes()
where typeof (IPresenter).IsAssignableFrom(type)
var first = presenters.FirstOrDefault();
if (first == null) throw new Exception("I expected to find at least one presenters!");
string viewNamespace = first.Namespace
viewNamespace = viewNamespace.Substring(0, viewNamespace.IndexOf(".Views")+6);
//yeah, that was hackish
var views = from view in Assembly.GetExecutingAssembly().GetTypes()
var table = new Dictionary<Type, Type>();
foreach (var view in views)
var presenter = GetPresenterForView(view, presenters);
if(presenter == null) continue;
private static Type GetPresenterForView(Type type, IEnumerable<Type> presenters)
string name = type.Name.Replace("View", "Presenter");
var presenter =
presenters.Where(p => p.Name == name).FirstOrDefault();
private static DataTemplate CreateDataTemplate(Type viewType, Type dataType)
var template = new DataTemplate(dataType);
var factory = new FrameworkElementFactory(viewType);
template.VisualTree = factory;
To use this, in your App.xaml.cs within OnStartup() add:
What do you think? Am I totally nuts?
Oh, and I should also point out that FrameworkElementFactory is actually deprecated. :-( Caveat emptor.