- KeldorKatarn
- Posts: 193
- Joined:
DataTemplate creation in code
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?
-
sfernandez
Site Admin
- Posts: 2983
- Joined:
Re: DataTemplate creation in code
Hi, the WPF framework is huge and we are implementing more and more things on each version based usually on the most requested features by our clients. If you find anything you need please don't hesitate to ask here in the forums and/or create a ticket in our bugtracker asking for it.
We support the basic version of XamlReader.Parse with just a string. In this case you have to provide the namespaces directly in the xaml:So first of all, ParserContext doesn't exist. So I'm missing that one. I am also missing XamlTypeMapper.
Code: Select all
string XamlTemplate =
$"<DataTemplate\n" +
$" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n" +
$" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n" +
$" xmlns:vm=\"clr-namespace:{viewModelType.Namespace};assembly={viewModelType.Assembly.GetName().Name}\"\n" +
$" xmlns:v=\"clr-namespace:{viewType.Namespace};assembly={viewType.Assembly.GetName().Name}\"\n" +
$" DataType=\"{{x:Type vm:{viewModelType.Name}}}\">\n" +
$" <v:{viewType.Name} />\n" +
$"</DataTemplate>";
When no explicity string key is provided we use the DataType of the DataTemplate as key for the ResourceDictionary. We do the same for Styles where we use the TargetType as key.The DataTemplate type is missing the DataTemplateKey property, so I cannot add it to the dictionary.
We also have a global application resource dictionary but I just noticed there is no API in C# to obtain it. I created ticket #1962 to add it for next release.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?
- KeldorKatarn
- Posts: 193
- Joined:
Re: DataTemplate creation in code
But why do I get an error in Unity then? Unity complains that I need to provide a key manually.When no explicity string key is provided we use the DataType of the DataTemplate as key for the ResourceDictionary.
-
sfernandez
Site Admin
- Posts: 2983
- Joined:
Re: DataTemplate creation in code
Please see my answer to your other post: viewtopic.php?f=3&t=2256&p=12448#p12448
- KeldorKatarn
- Posts: 193
- Joined:
Re: DataTemplate creation in code
Thank you, that'll be what I need to make this work. I'm still hoping to get a nice little MVVM framework going here.We also have a global application resource dictionary but I just noticed there is no API in C# to obtain it. I created ticket #1962 to add it for next release.
The main issues with porting all of Caliburn.Micro are still it's handling of IoC with a static class, which just doesn't work well if you use the framework for multiple things at the same time,
and the action/message feature (which I honestly feel is a bit redundand and involved for a simple framework anyway.
I'll try to get some of the ViewModel base classes to work, to have an easy mechanic for the views to correspond in ContentControls to the viewmodels (by viewfinder and the automatic DataTemplate generation) and see whether that works. I will not add the EventAggregator since there's plenty stuff like that already in the Unity world, like in UniRx.
-
sfernandez
Site Admin
- Posts: 2983
- Joined:
Re: DataTemplate creation in code
Great, we will love to see that framework up and running with Noesis :)
Re: DataTemplate creation in code
Our development is fully based on the feedback from our clients. It is true that we have many fronts, but please, insists on the missing things or issues you find. Make sure you create reports in the tracker for each issue separately (reports including many problems or being too generic are hard to close and have less priority). Don't worry about creating many tickets, that's better for us. And if possible, include a clear repro case. This increases the chances of solving it.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.
Thanks!
Who is online
Users browsing this forum: Google [Bot] and 69 guests