peer754
asked on
Mapping TreeView to/from xmldoc
Hi,
Developing a trad win app using VS 2010 C#.
Starting from loading a xml file into a XMLDocument object.
Next thing I do is load the xml nodes into a TreeView component (System.Windows.Forms)
Now I have a multi column ListView to show the attributes whenever user selects a node from the TreeView component. Here's where it all gets totally wrong. My first idea was to use the tv.SelectedNode.Index (in the TreeView event listener _AfterSelect). But since this index is calculated relatively its parent the mapping to the xmlNodes is lost.
So, is there a way you can do this using these standard components or do I need to design my own?
Cheers!
Developing a trad win app using VS 2010 C#.
Starting from loading a xml file into a XMLDocument object.
openedFile = someFile.xml;
xmlReader = new XmlTextReader(openedFile);
Global.mainXMLDoc.Load(xmlReader);
xmlReader.Close();
Next thing I do is load the xml nodes into a TreeView component (System.Windows.Forms)
private void AddNodeToTreeView(ref XmlNode inXmlNode, ref TreeNode inTreeNode)
{
XmlNode xNode;
TreeNode tNode;
XmlNodeList nodeList;
if (inXmlNode.HasChildNodes)
{
nodeList = inXmlNode.ChildNodes;
for (int i = 0; i <= nodeList.Count - 1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.Nodes[i];
AddNodeToTreeView(ref xNode, ref tNode);
}
}
}
Now I have a multi column ListView to show the attributes whenever user selects a node from the TreeView component. Here's where it all gets totally wrong. My first idea was to use the tv.SelectedNode.Index (in the TreeView event listener _AfterSelect). But since this index is calculated relatively its parent the mapping to the xmlNodes is lost.
private void treeView_AfterSelect(object sender, TreeViewEventArgs e, TreeView tv, ListView lv)
{
lv.Items.Clear();
ListViewItem lvItem;
currentNodeName = tv.SelectedNode.Text;
int currentNodeIx = tv.SelectedNode.Index;
xmlNodes = Global.mainXMLDoc.GetElementsByTagName(currentNodeName);
XmlNode xNode = xmlNodes.Item(currentNodeIx);
string attr;
string val;
for (int i = 0; i < xNode.Attributes.Count; i++)
{
attr = xNode.Attributes[i].Name;
val = xNode.Attributes[i].Value;
lvItem = new ListViewItem(attr);
string foo = FindXPath(xNode.Attributes[i]);
lvItem.SubItems.Add(val);
lvItem.SubItems.Add(foo);
lv.Items.Add(lvItem);
}
}
So, is there a way you can do this using these standard components or do I need to design my own?
Cheers!
in your XML file... are there any unique properties on each node? say an ID of sorts? or can you post a sample of of the xml file.
ASKER
Noop, but I'm gonna try to use the HashCode function from the xmlNode object but how do I know that this would be unique for every xml node?
Here's a small sample from my xml:
Here's a small sample from my xml:
<Organisation>
<MainGroup dataName="SA">
<HeadGroup dataName="SAA">
<PlannerGroup dataName="C02"></PlannerGroup>
<PlannerGroup dataName="C03"></PlannerGroup>
<PlannerGroup dataName="C04"></PlannerGroup>
<PlannerGroup dataName="C05"></PlannerGroup>
</HeadGroup>
<HeadGroup dataName="SAB">
<PlannerGroup dataName="C36"></PlannerGroup>
<PlannerGroup dataName="C37"></PlannerGroup>
</HeadGroup>
</MainGroup>
<MainGroup dataName="SB">
<HeadGroup dataName="SBB">
<PlannerGroup dataName="C12"></PlannerGroup>
<PlannerGroup dataName="C13"></PlannerGroup>
<PlannerGroup dataName="C14"></PlannerGroup>
<PlannerGroup dataName="C15"></PlannerGroup>
<PlannerGroup dataName="C23"></PlannerGroup></HeadGroup>
<HeadGroup dataName="SBC">
<PlannerGroup dataName="C30"></PlannerGroup>
<PlannerGroup dataName="C31"></PlannerGroup>
<PlannerGroup dataName="C32"></PlannerGroup>
</HeadGroup>
<HeadGroup dataName="SBD">
<PlannerGroup dataName="C41"></PlannerGroup>
<PlannerGroup dataName="C44"></PlannerGroup>
</HeadGroup>
<HeadGroup dataName="SBE">
<PlannerGroup dataName="C19"></PlannerGroup>
</HeadGroup>
</MainGroup>
</Organisation>
<World>
<Region dataName="Region North America" ShortName="RNA">
<SubRegion dataName="11">
<Country dataName="US" LongName="United States"/>
<Country dataName="CA" LongName="Canada"/>
</SubRegion>
</Region>
<Region dataName="Region Latin America" ShortName="RLA">
<SubRegion dataName="21">
<Country dataName="BM" LongName="Bermuda"/>
</SubRegion>
<SubRegion dataName="22">
<Country dataName="BB" LongName="Barbados"/>
<Country dataName="CO" LongName="Colombia"/>
<Country dataName="PE" LongName="Peru"/>
<Country dataName="VE" LongName="Venezuela"/>
</SubRegion>
<SubRegion dataName="24">
<Country dataName="BO" LongName="Bolivia"/>
<Country dataName="CL" LongName="Chile"/>
</SubRegion>
</Region>
</World>
you can use XPath to find the right node... not clean, but might work. to do this... perhaps start with this change - this keeps track of more details there:
should be:
do you have a screenshot of what the multi column ListView should look like?
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
should be:
TreeNode newNode = new TreeNode();
newNode.Text = xNode.Name;
newNode.Text = xNode.Attributes["dataName"].Value;
inTreeNode.Nodes.Add(xn);
do you have a screenshot of what the multi column ListView should look like?
i the HashCode can give us a unique value then by all means! use that! it "might" make life "easier". we will still have the problem of linking the hashcode back to the XML file
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Using the HashCode to map a TreeNode to/from a XMLNode seems to do the trick!