开发者

WPF XPath Binding With Multiple Results Converted to Comma-Delimited String

I have an XML file similar in structure to the following:

<Parent>

<Child>5</Child>

<Child>3</Child>

<Child>5</Child>

<Child>1</Child>

</P开发者_StackOverflowarent>

In my XAML, I have a ListView bound to the XML file and have set the DataTemplate of a ListViewItem to be bound as follows:

<TextBlock Text="{Binding XPath=Parent/Child}"/>

Obviously, I'm expecting 4 results for this XPath query, but I can't seem to find a way to convert the results to a comma-delimited string, and right now, the TextBlock is just displaying the first value.

If I use the same XPath query for setting the ItemsSource of a ListBox, I get all the results in the ListBox, so I think I should be able to get all the values passed to a Converter class...


There's no way to have an XPath query that returns multiple nodes, such as yours, aggregate them into a single value for you. What's happening is that a nodeset is being returned and, since you're binding to a single string property, the infrastructure is simply coercing that nodeset by grabbing the first node from the set and then grabbing its @text node.

Honestly I have not tried this myself and don't have time at the moment, but the only way I'd expect this to ever work is if you wrote a custom IValueConverter. I assume that it will hand an XmlNodeList as the value to be converted and then you can enumerate those nodes and concatenate a comma separated string yourself.

Update

Since the IValueConverter suggestion did not work due to the XPath engine doing a pre-coercion, here's what I suggest you do: instead of binding to a single TextBlock, bind to an ItemsControl instead and define the ItemTemplate for the ItemsControl to be as follows:

<DataTemplate>
    <TextBlock Text="{Binding}"/>,
</DataTemplate>

Note: in all honesty I'm taking the lazy approach in the DataTemplate and you will end up with a comma even after the last item right now. That said you should be able to define a DataTemplate with a trigger that determines that it's the last item and doesn't show the comma.

Finally, depending on how you want the data to layout also set the ItemsControl's ItemsPanel. I'm assuming you want horizontal flow with wrapping here:

<ItemsPanelTemplate>
    <WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>


If you want to set the XML data as source to your ListView you can do like this:

MyListView.ItemsSource = XElement.Load(@"XMLFile1.xml").Elements("Child");

and you bind to the Value property in the TextBlock:

<TextBlock Text="{Binding Path=Value}" />

If you need to modify the query you can extract the content of your XML file to a var that you can use as ItemsSource on your ListView.

XElement xmlData = XElement.Load(@"XMLFile1.xml");
var query = from x in xmlData.Elements("Child")
            select x;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜