HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Trying to un-hack this DataTemplateSelector

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thistryingdatatemplateselectorhack

Problem

I'm trying to emulate the default behavior of an ItemsControl in a ContentControl--Bind Content to an object property and use the correct DataTemplate based on that object's type.

I've tried to Reflector dotPeek at the implementation of the ItemsControl to see how it works, but I've reached a dead end. Consequently, I've come up with this custom DataTemplateSelector. Here's the code, after which I'll describe why it sucks.

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Markup;
namespace TemplateSelectorAndInheritance
{
///
/// A that finds
/// DataTemplates by the bound object's .
///
/// This selector supports keys defined by both the
/// and the type name specified by namespace
/// (xmlns).
public sealed class TypeBasedDataTemplateSelector : DataTemplateSelector
{
///
/// When overridden in a derived class, returns a
/// based on custom logic.
///
/// The data object for which to select the template.
/// The data-bound object.
///
/// Returns a or null. The default
/// value is null.
public override DataTemplate SelectTemplate(
object item, DependencyObject container)
{

if (item == null)
return null;
if (container == null)
throw new ArgumentNullException("container");
return FindFirstDataTemplate(
item.GetType(),
container as FrameworkElement);
}
///
/// Recursively searches up the visual tree searching for an applicable template.
///
/// The of the template
///
/// if found, null otherwise.
private DataTemplate FindFirstDataTemplate(
Type type,
FrameworkElement frameworkElement)
{

Solution

I think first of all you should get rid of looking for dataTemplates by type name. Then instead of your method you will be able to use FindResource method:

var resourceKey = new DataTemplateKey { DataType = type };
var dataTemplate = (DataTemplate)frameworkElement.FindResource(resourceKey);


Regarding your second question: I think it doesn't matter which one you will take first, as far as I remember they are mutually exclusive. Also MSDN says:


For templates, the Parent of the template eventually will be null. To get past this point and extend into the logical tree where the template is actually applied, use TemplatedParent

So taking this statement into account I would take Parent ?? TemplatedParent.

Code Snippets

var resourceKey = new DataTemplateKey { DataType = type };
var dataTemplate = (DataTemplate)frameworkElement.FindResource(resourceKey);

Context

StackExchange Code Review Q#2970, answer score: 2

Revisions (0)

No revisions yet.