DataTemplate + MVVM
Asked Answered
C

2

5

I'm using MVVM and each View maps to a ViewModel with a convention. IE MyApp.Views.MainWindowView MyApp.ViewModels.MainWindowViewModel

Is there a way to remove the DataTemplate and do it in C#? with some sort of loop?

<DataTemplate DataType="{x:Type vm:MainWindowViewModel}">
    <vw:MainWindowView />
</DataTemplate>
Carnal answered 10/1, 2010 at 2:11 Comment(0)
V
6

So basically, you need to create data templates programmatically... That's not very straightforward, but I think you can achieve that with the FrameworkElementFactory class :

public void AddDataTemplateForView(Type viewType)
{
    string viewModelTypeName = viewType.FullName + "Model";
    Type viewModelType = Assembly.GetExecutingAssembly().GetType(viewModelTypeName);

    DataTemplate template = new DataTemplate
    {
        DataType = viewModelType,
        VisualTree = new FrameworkElementFactory(viewType)
    };

    this.Resources.Add(viewModelType, template);
}

I didn't test it, so a few adjustments might be necessary... For instance I'm not sure what the type of the resource key should be, since it is usually set implicitly when you set the DataType in XAML

Volvulus answered 10/1, 2010 at 2:34 Comment(0)
C
6

Thanks Thomas, using your code i've done this.

You need to use the DataTemplateKey when adding the resoures :D

    private void AddAllResources()
    {
        Type[] viewModelTypes = Assembly.GetAssembly(typeof(MainWindowViewModel)).GetTypes()
            .Where(t => t.Namespace == "MyApp.ViewModels" && t.Name.EndsWith("ViewModel")).ToArray();

        string viewName = null;
        string viewFullName = null;

        foreach (var vmt in viewModelTypes)
        {
            viewName = vmt.Name.Replace("ViewModel", "View");
            viewFullName = String.Format("MyApp.Views.{0}, MyApp", viewName);

            DataTemplate template = new DataTemplate
            {
                DataType = vmt,
                VisualTree = new FrameworkElementFactory(Type.GetType(viewFullName, true))
            };

            this.Resources.Add(new DataTemplateKey(vmt), template);
        }
    }
Carnal answered 10/1, 2010 at 3:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.