2

We would like to create an application that can be quickly and easily "re-skinned" with as much flexibility as possible. Usually this is achieved through swapping out templates and styles in a resource dictionary.

Custom controls in WPF are designed to be "lookless." All of the logic goes in code, control templates in dictionaries are used to associate a look with the control.

There is a lot of overlap between MVVM and custom controls. A lot of developers say that MVVM trumps custom controls. Both can be viewed as methods of moving logic out of the view and into another code file. I think there can be semantic difference between the two if a VM contains domain related logic while custom controls contain view-specific logic.

What is the best method for moving the relevant view XAML into a resource dictionary that can be swapped out? Should I use straight data templates in a dictionary (not my preferred method because the views are complex)? Should I create a custom control to replace the view and define a control template for it (results in duplicate code between the control and the VM)? Should I use UserControls for the views and isolate the XAML for these controls so that these files can be swapped out with the resource dictionaries?

How would you handle this problem? Any suggestions?

Thanks!

Josh G
  • 14,068
  • 7
  • 62
  • 74
  • 2
    MVVM and a custom control are not competing approaches to a problem. – Aaron McIver Apr 25 '11 at 14:54
  • Try to use both at the same time and you will see that there can be a lot of overlap between the two. It depends on the scenario. – Josh G Apr 25 '11 at 15:27
  • I use whole resource dictioinaries with like skinned control temples and naming conventions that match. All you have to do is re-link the dictionary at run time to re-skin. – CodeWarrior Apr 25 '11 at 20:24
  • @Cory The CodeWarrior: This works great for conventional WPF apps. I thought doing the same for my MVVM app would be simple, but it hasn't turned out to be so. My views are currently defined in UserControls and I don't know how to re-skin a UserControl. – Josh G Apr 25 '11 at 20:44
  • 2
    My Views are UserControls too, but I restyle indivisual elements in the control, not the whole control. So TextBoxes will have TextBox1 Template, Comboboxes will have ComboBox1 Template etc. At run time when I unlink from NormalResDict.xaml and link to HighContrastDarkResDict.xaml, my templates are named the same, and all of the elements follow suit. Out of curiosity, how are your UserControls arranged? – CodeWarrior Apr 25 '11 at 20:54
  • Hmm... This line of thought has some potential. Nothing out of ordinary on the arrangement. Just a visual tree of nested controls bound to the relevant properties on the VM. I was hoping to allow for more flexibility with re-skinning, but it's possible that I could do it by putting ContentControls and other stuff in the UserControl and applying predefined styles to these controls. – Josh G Apr 25 '11 at 21:18

1 Answers1

2

Personally I like using an using an IValueConverter like this post.

This basically requires you to:

  • Put one entry in your application resources to require WPF use the value converter
  • Implement the IValueConverter with the custom logic you want.

This allows you as much flexibility as you deem necessary for your application. The post above uses a convention over configuration look up strategy, but you can easily swap that out for a converter that relies on a service that you can register/resolve objects like so:

public static class ServiceProvider
{
  public void Register<TView>(Type ViewModelType);
  public void Register(IDictionary<Type,Type> ViewLookup);
  public object Resolve(object ViewModel);
}

HTH

Community
  • 1
  • 1
Jose
  • 10,891
  • 19
  • 67
  • 89
  • I like this idea. It takes a little bit of imagination to apply this to creating lookless views, but I think it has potential. This should allow us to more easily swap out the views anyway. – Josh G Apr 26 '11 at 13:02