Как применить DataTemplate к подклассу XElement? - PullRequest
0 голосов
/ 19 апреля 2009

когда я делаю подкласс из XElement, DataTemplate, который работает для XElement, используя имя элемента как DataType, не работает для подкласса. Есть идеи?

<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="batman@jabber.org" subscription="none" />
    <contacto jid="trucoman@jabber-hispano.org" subscription="both" name="truco" />
    <contacto jid="mmakinavaja@gmail.com" subscription="none" name="mmakinavaja" />
    <contacto jid="ramon@jabber-hispano.org" subscription="both" name="Ramon" />
 </grupo>
 <grupo name="Lannisters">
    <contacto jid="jamie@jabberes.org" subscription="none" />
 </grupo>
 <contacto jid="tyrion@jabber.org" subscription="none" />
   <contacto jid="nslbot@jabber.org" subscription="none" />
   <contacto jid="nslbot@jabberes.org" subscription="none" />
</contactos> -->  

1 Ответ

0 голосов
/ 23 апреля 2009

Я знаю, почему это не работает, но я не понимаю, почему это реализовано так, как есть. Глядя с помощью рефлектора кода из метода "FindTemplateResourceInternal" я нашел ответ:

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

Хорошо, я понимаю, что полное имя моего класса не System.Xml.Linq.XElement. Но позже, как только вы окажетесь внутри "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;
}

Внутри этого цикла, после "baseType=baseType.BaseType", если вы проверите еще раз FullName, теперь это XElement ... Но вместо этого он теперь ищет DataTemplate с DataType={x:Type XElement} ...

...