XML To-&-From: File & XML & Infragistics Hierarcal UltraGrid
Moving data to/from hierarchical data is tricky. This will help.
Introduction
XML, Infragistics.Win.UltraWinGrid and hierarchical data in WinForms using VB.NET (also known as hierarchy, hierarchical, hierarchic, hierarchically, hierarchism, tree, parent child).
Background
Hierarchical data can be a "tough-nut-to-crack!" But, XML is quite comfortable with it and Infragistics UltraWinGrid chews-it-up and spits-it-out ten different ways! So the tools do exist, but moving data TO-FROM proved quite difficult.
First! I am NOT PROUD of what I'm posting. It has "kludge" written all over it and the word "elegant" simply does not apply. BUT THE CODE WORKS!
Using the Code (also see Versioning below)
The first hurdle is understanding how hierarchical data is stored in a Data Set. A hierarchical data source is a strange beastie! First we start with a DataSet, a DataSet is composed of TWO or more Data Tables. Hierarchical data uses two or more Data Tables joined using Relations!
So, if we're pushing the below XML into a DataSet ...
<
Nodename="Animal">
<Nodename="Reptile">
<Nodename="Turtle" />
<Nodename="Lizard" />
</Node>
<Nodename="Mammal">
<Nodename="Cat" />
<Nodename="Dog" >
<Nodename="Retriever" />
</Node>
</Node>
</Node>
... our DataSet needs 4(four) data tables, one for each Level of Nesting!
Data Table | Data |
1st Data Table contains one record | "Animal" |
2nd Data Table contains two records | "Reptile" "Mammal" |
3rd Data Table contains four records | "Turtle" "Lizard" "Cat" "Dog" |
4th Data Table contains one record | "Retriever" |
Okay, that's the data, but what about the Relations? To be able to relate the data correctly, our first task is to add a UNIQUE identifier to every record (in the demo project we use GUIDs). So ...
Data Table | Data | UniqueID |
1st Data Table contains one record | "Animal" | "AAA" |
2nd Data Table contains two records | "Reptile" "Mammal" | "BBB" "CCC" |
3rd Data Table contains four records | "Turtle" "Lizard" "Cat" "Dog" |
"ZZZ"
"YYY" "XXX" "WWW" |
4th Data Table contains one record | "Retriever" | "HHH" |
Okay every record in every data table now has a unique identifier. So now we need to add build and add Parent-Child keys pointing at the proper relations, so (look carefully!)
Data Table | Data | UniqueID | ParentID |
1st Data Table contains one record | "Animal" | "AAA" | nothing |
2nd Data Table contains two records | "Reptile" "Mammal" |
"BBB" "CCC" |
"AAA" "AAA" |
3rd Data Table contains four records | "Turtle" "Lizard" "Cat" "Dog" | "ZZZ" "YYY" "XXX" "WWW" | "AAA-BBB" "AAA-BBB" "AAA-CCC" "AAA-CCC" |
4th Data Table contains one record | "Retriever" | "HHH" | "AAA-CCC-WWW" |
And if you map the above data structure to a hierarchical representation.
UniqueID | ParentID | |
Animal Reptile Turtle Lizard Mammal Cat Dog Retriever |
AAA | |
BBB | AAA | |
CCC | AAA-BBB | |
YYY | AAA-BBB | |
CCC | AAA | |
XXX | AAA-CCC | |
WWW | AAA-CCC | |
HHH | AAA-CCC-WWW |
So ... as you pull-in the XML from the file, the hard part is keeping track of where you are and putting the incoming node into the correct Data Table and assigning a UniqueID and building the ParentID properly! Much easier said ... than done.
And remember, once the is DataSet is built and passed to UltraWinGrid, the UltraWinGrid throws away the DataSet, throws away the DataTables and throws away the DataRelations! When it's done throwing stuff away, all UltraWinGrid has, is a pool of random rows which are organized as Siblings & Children ... which can only be accessed using calls like ...
SiblingRow.First | ChildRow.First |
SiblingRow.Last | ChildRow.Last |
SiblingRow.Next | |
SiblingRow.Previous |
So ... walking a hierarchical UltraWinGrid, row by row and re-assembling the XML properly is quite daunting. But, no worries, the sample code does it and shows you how.
Points of Interest
The sample has all four processes broken into four buttons. You can easily follow each process and see how each is done. The four processes are:
- XML file into UltraWinGrid
- UltraWinGrid into XML in memory
- XML in memory to UltraWinGrid
- UltraWinGrid to XML file
Another interesting point, XML can "crash" if certain characters are used in
data. So, since this demo uses the brute force method of assembling XML, by
using simple strings, it is necessary to prevent the bad-characters from
appearing, so I use System.Web.HttpUtility.HtmlEncode
and
System.Web.HttpUtility.HtmlDecode
on all XML data to prevent problems.
Versioning
The Sample VB.net source code should run right out of the ZIP file. However, if you're NOT using Infragistics NetAdvantage 10.2 Win CLR2x ... No Worries! Just open the Sample Application, delete the two UltraGrids and drop whatever version UltraGrid you're using back into the same UI holes. They should be named like the ones you deleted ...
- Name: UltraGrid1 - DockStyle: Left
- Name: UltraGrid2 - DockStyle: Right
History
Aug 8, 2012 - Project posted to CodeProject