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
|