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