Sunday, March 10, 2013

WPF - How to run XPath count() in XmlDataProvider binding

Hi,
Welcome to my very first (not really) blogging entry. I was monkeying around with an issue on internet and could not find any solution, however, I did find quite a few people looking for the same thing I was looking for. I tried something that worked, thought I would share that with the world.

So the issue is, You have the following Xml to bind to in your WPF application

 <MyData>  
  <Book Name="WPF Basics" Author="John Doe">  
   <Publishers>  
    <Publisher>  
     <Name>Wrox </Name>  
     <Name>Microsoft Press</Name>  
    </Publisher>  
   </Publishers>  
  </Book>  
  <Book Name="Thinking in WPF" Author="Johny Cage">  
   <Publishers>  
    <Publisher>  
     <Name>Wrox </Name>  
    </Publisher>  
   </Publishers>  
  </Book>  
 </MyData>  

Now you have a Listview that displays Book name in one column and number of Publishers in other column.

If WPF XmlDataProvider supported XPath functions you could do something like this for 2nd column

{Binding XPath=count(Publishers/Publisher)}

But XmlProvider binding uses SelectNodes() of XmlNode in System.Xml which does not take XPath functions.

Another way I was able to think of was to use converters and do something like this

{Binding XPath=Publishers/Publisher, Converter=myOwnNodeListToCountConverter}

But XmlDataProvider calls the .ToString() before passing it on to your converter. Which means, your converter won't get an XmlNodeList object, but just an empty string.


So lastly, I tried this which finally worked, Not an elegant way but it works. :)

The basic idea is to render all the items you want to count in an invisible (Visibility=Collapsed) ItemsControl and Bind a TextBlock to the Items.Count of that ItemsControl. Here is a little snippet to show the concept.


<ListView IsSynchronizedWithCurrentItem="True" Margin="8,8,0,0" ItemsSource="{Binding Source={StaticResource xmlFmlDataSource}, XPath=//Programs/Program, Mode=OneWay}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Book name" Width="200" DisplayMemberBinding="{Binding XPath=@Name}"  >
           
                    </GridViewColumn>
                    <GridViewColumn Header="Params" Width="50" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel>
                                <ItemsControl x:Name="dummyItemsControl" ItemsSource="{Binding XPath=Publishers/Publisher}" Visibility="Collapsed">
                                    <ItemsControl.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="" />
                                        </DataTemplate>
                                    </ItemsControl.ItemTemplate>
                                </ItemsControl>
                                <TextBlock Text="{Binding ElementName=dummyItemsControl, Path=Items.Count}" />
                                </StackPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>



This is not my dream solution that I feel ecstatic about, but this works and won't probably a big deal if the data volume is not too large. I would love to read your comments.

1 comment:

  1. sekarang ini banyak sekali pria yang membutuhkan viagra asli usa cod di lippo cikarang sebagai salah satu obat untuk meningkatkan gairah bercinta bersama pasangan. lihat selengkapnya kini banyak wanita yang merasa senang semenjak suaminya mengonsumsi viagra asli usa 100 mg cod di karawang karena staminanya jadi lebih kuat ketika berhubungan intim baca disini . nama viagra asli usa 100mg cod di semarang semakin populer semenjak para pria telah sukses saat berhubungan badan dengan istrinya info selengkapnya . sejak saat itu kedua pasangan bisa merasakan kepuasan dalam melakukan hubungan badan ketika diranjang dan bisa mencapai klimaks yang sangat memuaskan hanya dengan meminum 1 tablet viagra asli usa 100 mg cod di bandung .

    ReplyDelete