Use specific templates depending on the value of the object in the dynamic source.

0 Answers 15 Views
GridView
Radek
Top achievements
Rank 1
Radek asked on 17 Feb 2022, 11:34 PM

Hi,
I am creating a generic grid solution, based on the Telerik grid with dynamic data source.
This is my ItemsSource:

var data = new ObservableCollection<MyDataRow>(); //DynamicObject

Where MyDataRow is created from 2D array of various objects (MyClass, Strings, etc).

And I would like to choose template based on value (or type of object) which will be presented in the cell, but the only way, that achieved the desired result, was to add TemplateSelector which dynamicly creates a concrete datatemplate for each column/cell.
Simplified version of my Selector:

public class MyTemplateSelector : DataTemplateSelector
{
	public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
	{
		if(container is GridViewCell gridViewCell && item != null)
		{
			int columnIndex = gridViewCell.Column.DisplayIndex;
			DataTemplate dataTemplate = null;
			MyDataRow myDataRow = item as MyDataRow;
			if (myDataRow["Column" + columnIndex] is MyClass)
			{	// Template example 1
				StringReader stringReader = new StringReader(
				@"<DataTemplate 
				xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> 
					<TextBlock Text=""{Binding Column" + columnIndex + @".ResultText}""/> 
				</DataTemplate>");
				XmlReader xmlReader = XmlReader.Create(stringReader);
				dataTemplate = XamlReader.Load(xmlReader) as DataTemplate;
			}
			else
			{   // Template example 2
				StringReader stringReader = new StringReader(
				@"<DataTemplate 
				xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> 
					<TextBlock Text=""{Binding Column" + columnIndex + @"}""/> 
				</DataTemplate>");
				XmlReader xmlReader = XmlReader.Create(stringReader);
				dataTemplate = XamlReader.Load(xmlReader) as DataTemplate;
			}
			if (!dataTemplates.ContainsKey(columnIndex))
			{
				dataTemplates.Add(columnIndex, dataTemplate);
			}
			return dataTemplates[columnIndex];
		}
		return null;
	}
	// Dictionary of already defined templates
	Dictionary<int, DataTemplate> dataTemplates = new Dictionary<int, DataTemplate>();
}

So in this case, there can be up to c*x number of slightly different templates:
(c - number of columns, x - number of specific templates)

Is there any more performance wise or clearer way to solve this problem?

Thank you for any help.

Martin Ivanov
Telerik team
commented on 22 Feb 2022, 12:43 PM

Given the specific requirement, there is no more clever approach that I can suggest. If possible, you can hard-code the templates in a ResourceDictionary and assign them to the selector. This is a bit rough, but it will be better when it comes to performance. Another, idea that you can try is to cache the created templates in a dictionary (which you are already doing) and decide if a template should be re-used or a new one should be created. 

No answers yet. Maybe you can help?

Tags
GridView
Asked by
Radek
Top achievements
Rank 1
Share this question
or