WPF MVVM: Convention over Configuration for ResourceDictionary?

后端 未结 2 770
清酒与你
清酒与你 2020-12-01 03:56

Update

In the wiki spirit of StackOverflow, here\'s an update:

I spiked Joe White\'s IValueConverter suggestion below. It works like a charm. <

相关标签:
2条回答
  • 2020-12-01 04:46

    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.

    0 讨论(0)
  • 2020-12-01 04:47

    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

    0 讨论(0)
提交回复
热议问题