views:

260

answers:

2

Hi, when I subclass from XElement, the DataTemplate that works for XElement using the element name as DatatType, doesn't work for the subclass. Any idea?

<HierarchicalDataTemplate DataType="grupo" ItemsSource="{Binding Path=Elements}">
        <TextBlock Text="{Binding Path=Attribute[name]}" />
</HierarchicalDataTemplate>
<!-- When I build an XDocument with XElements like this the template gets applied -->
XDocument _xdoc=XDocument.Load(@"RosterData1.xml");
treeRoster.DataContext = _xdoc;     
<TreeView Name="treeRoster" ItemsSource={Binding Path=Root.Elements}>
</TreeView>  
<!-- but if build de XDocument like this the DataTemplate doesn't apply -->
XDocument _xdoc=XDocument.Load(@"RosterData1.xml");
XDocument docOther = new XDocument(new XElement("contactos"));
var grupos = _xdoc.Descendants("grupo").Select(g => new Grupo(g));
docOther.Root.Add(grupos.ToArray());
var contactos = _xdoc.Root.Elements("contacto").ToList();
docOther.Root.Add(contactos);
treeRoster.DataContext = docOther;  
<!-- The xml file is like that:
<contactos>
  <grupo name="Amigotes">
    <contacto jid="[email protected]" subscription="none" />
    <contacto jid="[email protected]" subscription="both" name="truco" />
    <contacto jid="[email protected]" subscription="none" name="mmakinavaja" />
    <contacto jid="[email protected]" subscription="both" name="Ramon" />
 </grupo>
 <grupo name="Lannisters">
    <contacto jid="[email protected]" subscription="none" />
 </grupo>
 <contacto jid="[email protected]" subscription="none" />
   <contacto jid="[email protected]" subscription="none" />
   <contacto jid="[email protected]" subscription="none" />
</contactos> -->
A: 

i was wrong...

A: 

I know why it doesn't work, but i don't understand why it is implemented the way it is. Looking with reflector the code from the method "FindTemplateResourceInternal" i've found the answer:

Type baseType = item.GetType();
if ((baseType.FullName == "System.Xml.Linq.XElement") && 
((obj2 = GetXLinqTagName(item, baseType)) != null))
{
    baseType = null;
}

Ok, I understand that my class' full name isn't System.Xml.Linq.XElement. But later, once you are inside the "while":

while (obj2 != null)
{
    object obj3 = null;
    if (templateType == typeof(DataTemplate))
    {
        obj3 = new DataTemplateKey(obj2);
    }
    if (obj3 != null)
    {
        keys.Add(obj3);
    }
    if (exactMatch == -1)
    {
        exactMatch = keys.Count;
    }
    if (baseType != null)
    {
        baseType = baseType.BaseType;
        //HERE baseType FullName is XElement
        //Why don't check it again??
        if (baseType == typeof(object))
        {
            baseType = null;
        }
    }
    obj2 = baseType;
}

Inside this loop, after "baseType=baseType.BaseType", if you check again FullName, now it is XElement... But instead, it is now looking for a DataTemplate with DataType={x:Type XElement}...