DataTemplate creation in code
Posted: 07 Apr 2021, 14:24
Hey guys, somehow whenever I try to take another shot at NoesisGUI I seem to keep doing things that are just beyond the limits of possibility.
Since I've completely given up on getting a MVVM Framework like Caliburn to run on Noesis since there's still API missing and Caliburn has other issues with it's static IoC,
I decided to do my own little framework. However I immediately ran into problems again, and one is related to the issues I had with caliburn. Parsing XAML.
But there's also another question that needs solving.
So I'm trying to use Views as DataTemplates so I can just databind a ContentControl to a ViewModel and the View is shown because it's the DataTemplate for that ViewModel type.
So far so good, that's a standard technique.
However I wanted to go a step further and didn't want to declare those DataTemplates one by one in some ResourceDictionary.
Instead I wanted to just look through all public types that match being a view and just create those DataTemplates dynamically.
I found a good code snipped online and got that to work in WPF, but unfortunately not in Noesis:
So first of all, ParserContext doesn't exist. So I'm missing that one. I am also missing XamlTypeMapper.
The DataTemplate type is missing the DataTemplateKey property, so I cannot add it to the dictionary.
And finally... what dictionary am I even adding this to?
In WPF I'm using Application.Current.Resources. What should I use in Unity for Noesis?
Is there a global dictionary or a NoesisView specific dictionary I can use to dynamically add resources?
I'm assuming for now I'm out of luck?
Since I've completely given up on getting a MVVM Framework like Caliburn to run on Noesis since there's still API missing and Caliburn has other issues with it's static IoC,
I decided to do my own little framework. However I immediately ran into problems again, and one is related to the issues I had with caliburn. Parsing XAML.
But there's also another question that needs solving.
So I'm trying to use Views as DataTemplates so I can just databind a ContentControl to a ViewModel and the View is shown because it's the DataTemplate for that ViewModel type.
So far so good, that's a standard technique.
However I wanted to go a step further and didn't want to declare those DataTemplates one by one in some ResourceDictionary.
Instead I wanted to just look through all public types that match being a view and just create those DataTemplates dynamically.
I found a good code snipped online and got that to work in WPF, but unfortunately not in Noesis:
Code: Select all
#region Using Directives
using System;
#if NOESIS
using Noesis;
#else
using System.Windows;
using System.Windows.Markup;
#endif
#endregion
public static class DataTemplateManager
{
#region Public Methods
public static void RegisterDataTemplate<TViewModel, TView>(ResourceDictionary dictionary)
where TView : FrameworkElement
{
RegisterDataTemplate(typeof(TViewModel), typeof(TView), dictionary);
}
public static void RegisterDataTemplate(Type viewModelType, Type viewType, ResourceDictionary dictionary)
{
DataTemplate template = CreateTemplate(viewModelType, viewType);
var key = template.DataTemplateKey;
dictionary.Add(key, template);
}
#endregion
#region Private Methods
private static DataTemplate CreateTemplate(Type viewModelType, Type viewType)
{
const string XamlTemplate = "<DataTemplate DataType=\"{{x:Type vm:{0}}}\"><v:{1} /></DataTemplate>";
var xaml = string.Format(
XamlTemplate,
viewModelType.Name,
viewType.Name);
var context = new ParserContext();
context.XamlTypeMapper = new XamlTypeMapper(new string[0]);
context.XamlTypeMapper.AddMappingProcessingInstruction(
"vm",
viewModelType.Namespace,
viewModelType.Assembly.FullName);
context.XamlTypeMapper.AddMappingProcessingInstruction(
"v",
viewType.Namespace,
viewType.Assembly.FullName);
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
context.XmlnsDictionary.Add("vm", "vm");
context.XmlnsDictionary.Add("v", "v");
var template = (DataTemplate)XamlReader.Parse(xaml, context);
return template;
}
#endregion
}
The DataTemplate type is missing the DataTemplateKey property, so I cannot add it to the dictionary.
And finally... what dictionary am I even adding this to?
In WPF I'm using Application.Current.Resources. What should I use in Unity for Noesis?
Is there a global dictionary or a NoesisView specific dictionary I can use to dynamically add resources?
I'm assuming for now I'm out of luck?