Multiple Level Master Detail Binding in WPF(XAML)

I’ve seen a couple of developers fumble with a LOT of Code when asked to implement a 2-3 level Master –detail form.

So we put together a bit of code to showcase how easily it can be done with virtually no code (alteast no code behind!!) in WPF

Consider the following problem statement:

Create a form which lists a set of families in a dropdown.(Level 1)

Depending on the family selected list the members of the family. List the sons and daughters in a dropdown(Level 2)

 

Depending on the son or daughter selected, list their friends in a dropdown(Level 3)

So your form should look like

To make things more interesting, all this information about the families comes from this XML Document. Family.xml

So how do we do this in WPF?.

The following 4 Step process should suffice!!

1.       Create an XML Data provider for the XML  Document and set the XPath to the Family Node

<XmlDataProvider x:Key=”dataSource” Source=”Family.xml” XPath=”/Families/Family”></XmlDataProvider> 

2.       Create the UI in 2 layers  i.e there should be 3 grids let’s call them the  FamilyGrid, Son Grid and Daughter Grid

So the structure is

<Grid x:Name=”FamilyGrid”>

<..Place the Level 1 controls here…i.e Family combobox, Father and Mother text blocks–>

                <Grid  x:Name=”SonGrid”>

<.. Place the Level 2 and Level 3 controls here..i.e the “Son” Combo box followed by the Son’s friends..>

                </Grid>

<Grid  x:Name=”DaughterGrid”>

<.. Place the Level 2 and Level 3 controls here..i.e the “Daughter” Combo box followed by the Daughter’s friends..>

</Grid>

                </Grid>

3.       Set the DataContexts of the Grids

a.       Family Grid: Set the DataContext to the Family Node

<Grid x: Name=”FamilyGrid” DataContext=”{Binding Source={StaticResource  dataSource}}”>

b.      Son Grid: Set the DataContext to the “Son” Node within the current Binding

<Grid x:Name=”SonGrid” DataContext=”{Binding XPath=Children/Sons/Son}”>

c.       Daughter’s Grid: Set the DataContext to the “Daughter” Node within the current Binding

<Grid x:Name=”DaughterGrid” DataContext=”{Binding XPath=Children/Daughters/Daughter}”>

4.       Bind the Comboboxes to the required fields and set the IsSynchronizedWithCurrentItem= true

 As Highlighted above the key points here are

·         The DataContexts of the Grids which are set to the level of information which we want to show. Whenever a control does an “ItemSource= {Binding…}, the compiler will travel up the UI Heirarchy to find the first not- null data context.So it helps to set the datacontext at the “container” level if mutiple controls need to refer to a common data source.

 

 Since we have a hierarchy of grids and the family grid refers to the /Families/Family Node, we just need to keep setting the DataContext={Binding , XPath= <the XPath to the Node following the family node>}. DataContext={ Binding…} will take you to the /Families/Family node and the XPath will take you to your desired node

 

·         The Property IsSynchronizedWithCurrentItem which is being set to true in the comboboxes is the key here.When you bind a set of data to a value select control and set IsSynchronizedWithCurrentItem = true, what you are saying is “From this point onwards consider this data item as the selected item and refer to it for data for the ensuing controls”

 

So when you select a family in the family combobox, and make it the “Current Selected” data item, the other comboboxes will refer to the data present in the selected family at the specified path , so Family/Son will search for the Son node within the selected Family

 So using a combination of DataContexts to refer to different levels of data and IsSynchronizedWithCurrentItem to set the currently selected data you can go upto n levels of master details binding,and you wudn’t have written a single line of code in you .cs fileJ

  You can find the solution for the above example here MasterDetailBinding.zip.

 Happy Detailing!

Cennest

Advertisements