Update
In the wiki spirit of StackOverflow, here\'s an update:
I spiked Joe White\'s IValueConverter suggestion below. It works like a charm. <
Rather than writing code to explicitly add things to the ResourceDictionary, how about just generating the right view on demand? You can do this with a ValueConverter.
Your resources would look like this:
<Views:ConventionOverConfigurationConverter x:Key="MyConverter"/>
<DataTemplate DataType="{x:Type ViewModels:ViewModelBase}">
<ContentControl Content="{Binding Converter={StaticResource MyConverter}}"/>
</DataTemplate>
You still need a DataTemplate resource, but as long as your ViewModels all have a common base class, you'll only need one DataTemplate to take care of all of them.
Then define the value converter class:
public class ConventionOverConfigurationConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
// value is the ViewModel. Based on its GetType(), build a string
// with the namespace-qualified name of the view class, then:
return Activator.CreateInstance(Type.GetType(viewName));
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
All you'd need to do is write the logic inside Convert, which will depend on things like whether your Views and ViewModels are in the same namespace or not.
I decided to do pretty much hthe same thing so I load my DataTemplates directly into the ResourceDictionary using
private void RegisterResources()
{
ResourceDictionary dictionary = new ResourceDictionary();
dictionary.Source = new Uri("pack://application:,,,/StartupModule;Component/UIResources.xaml");
Application.Current.Resources.MergedDictionaries.Add(dictionary);
}
where the UIResources file is a ResourceDictionary xamls file containing all of our DataTemplates