Binding XDocumentu - Elements a Attributes   zodpovězená otázka

WPF

Zdravím,

mám následující XDocument jako DataContext svého okna:

Class MainWindow
    Public Sub New()
        InitializeComponent()
        Me.DataContext = <?xml version="1.0" encoding="utf-8"?>
                         <Sketch Format="A4" Author="Alex" Created="..." Test="Value">
                             <Item Kind="Line" X1="50" Y1="50" X2="150" Y2="150">
                                 <Item Kind="Rect" X="10" Y="10" Width="30" Height="30"/>
                             </Item>
                             <Item Kind="Line" X1="250" Y1="250" X2="250" Y2="50">
                                 <Item Kind="Ellipse" X="10" Y="10" Width="30" Height="30"/>
                             </Item>
                             <Test Param="Value"/>
                         </Sketch>
    End Sub
End Class

V XAMLu testuji několik různých cest Bindingu. Všechny fungují, pokud binduji Elements, Element nebo Attribute, ale Attributes nefunguje. Elements i Attributes implementují IEnumerable. Elements a Element je zděděná od XContainer, Attributes a Attribute jsou vlastní XElementu.

<Window Height="320" Title="Main Window" Width="640" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MainWindow">
    <UniformGrid Columns="3">
        <StackPanel>
            <Label Foreground="DimGray">Root.Elements.Count</Label>
            <Label Content="{Binding Path=Root.Elements.Count}"/>
            <Label Foreground="DimGray">Root.Attributes.Count</Label>
            <Label Content="{Binding Path=Root.Attributes.Count}"/>
            <Label Foreground="DimGray">Root.Element[Test]</Label>
            <Label Content="{Binding Path=Root.Element[Test]}"/>
            <Label Foreground="DimGray">Root.Attribute[Test]</Label>
            <Label Content="{Binding Path=Root.Attribute[Test]}"/>
        </StackPanel>
        <StackPanel>
            <Label Foreground="DimGray">Root.Elements</Label>
            <ListBox ItemsSource="{Binding Root.Elements}"/>
            <Label Foreground="DimGray">Root.Attributes</Label>
            <ListBox ItemsSource="{Binding Root.Attributes}"/>
        </StackPanel>
        <StackPanel>
            <TreeView ItemsSource="{Binding Root.Elements}">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Elements}">
                        <Label Content="{Binding Name}"/>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </StackPanel>
    </UniformGrid>
</Window>

Jak jsem již říkal, všechen Binding kromě Attributes funguje. V Output okně dostanu zprávu, že:

System.Windows.Data Error: 40 : 
BindingExpression path error: 
Attributes property not found on object XElement (HashCode=6837024). 
BindingExpression:
Path=Root.Attributes.Count; 
DataItem=XDocument (HashCode=27433049); 
target element is Label (Name=""); 
target property is Content (type Object)

Toto je zvláštní hned z několika důvodů. Sice mi to ukazuje, že se na typu XElement nepodařilo najít vlastnost Attributes, což je pravda, ale je tam funkce Attributes. Koneckonců zděděná funkce Elements od XContaineru se nabinduje skvěle. A jak na XElementu, tak na XContaineru je to vždy funkce, žádný předek v rodokmenu XElementu nemá vlastnost Elements.

Pominu tedy slovo vlastnost dostáváme se k další zvláštní věci: člen Attributes se na XElementu nepodařilo najít, ačkoliv je mu vlastní, ale zděděný člen Elements se najít podařilo. Také, Attribute (jako člen vlastní XElement) se najde a nabinduje zcela správně v kontrastu s Attributes.

Napadlo mne, že ToString u XAttribute vrací prázdný řetězec a proto se mi nedaří výsledné prvky vizuálně identifikovat, ale to je nejen v rozporu s dokumentací a jednoduchým testem <promenna_xattribute>.ToString(), ale také jsem to vyloučil nabidnováním cesty Attributes.Count (binding neprojde, což znamená, že už samostatný binding Attributes nic nevrací).

Rodokmen XElement je proti XAttribute bohatší o dva stupně: XNode a XContainer. Na ani jedné z těchto tříd nevidím žádný speciální atribut/rozhraní, které by ho nějak zatraktivnili k bindingu proti XAttribute.

Nevidím zkrátka jediný důvod, proč XAttributes nabindovat nejde. Pokud někdo z vás nějaký takový najde, budu velmi vděčný.

S pozdravem,

Alex

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Důvodem, proč mi nešli nabindovat Attributes bylo to, že neexistuje tzv. Dynamic Property Attributes na typu XElement. Ostatní funkce (Element, Elements, Attribute) mají také Dynamic Property a proto binding fungoval tak, jak měl.

Zdroje:

http://msdn.microsoft.com/en-us/library/... - dynamic properties na MSDN

http://msdn.microsoft.com/en-us/library/... - dynamic properties typu XElement

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback