![]() |
A Node and its Children |
|
Introduction |
|
The other version of the TreeNodeCollection.Add() method uses the following syntax: public virtual int Add(TreeNode node); This method takes as argument a TreeNode object. In other words, it expects a complete or semi-complete branch already defined somehow. |
|
The TreeNode class is equipped with various constructors you can use to instantiate it. Its default constructor allows you to create a node without primarily giving its details. Another TreeNode constructor has the following syntax: public TreeNode(string text); This constructor takes as argument the string that the node will display. Here is an example of using it and adding its newly create node to the tree view: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 280);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 230;
TreeNode nodElement = new TreeNode("World");
tvwCountries.Nodes.Add(nodElement);
Controls.Add(tvwCountries);
}
We mentioned that the primary characteristic of a node is the text it displays. The text of a node is stored in a property of the TreeNode class and is called Text. This allows you either to specify the string of a node or to retrieve it when needed. Here is an example of setting it: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 280);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 230;
TreeNode nodElement = new TreeNode();
nodElement.Text = "World";
tvwCountries.Nodes.Add(nodElement);
Controls.Add(tvwCountries);
}
Just as we called the TreeNodeCollection.Add() method to create a branch, you can call it as many times as necessary to create additional branches. Here is an example: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 280);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 230;
tvwCountries.Nodes.Add("World");
tvwCountries.Nodes.Add("Jupiter");
tvwCountries.Nodes.Add("Neptune");
tvwCountries.Nodes.Add("Uranu");
Controls.Add(tvwCountries);
}
This would produce:
Alternatively, if you have many branches to add to the tree, you can first create them as an array of TreeNode values, then called the TreeNodeCollection.AddRange() method. The syntax of this method is: public virtual void AddRange(TreeNode[] nodes); This method takes as argument an array of TreeNode objects. Here is an example: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 280);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 230;
TreeNode[] nodPlanets =
{
new TreeNode("World"),
new TreeNode("Jupiter"),
new TreeNode("Neptune"),
new TreeNode("Uranu")
};
tvwCountries.Nodes.AddRange(nodPlanets);
Controls.Add(tvwCountries);
}
At design time and in the TreeNode Editor, to create a child node for an existing item, first select it in the Select Node To Edit list, then click the Add Child button. This causes a child node to be created for the selected item. To edit its name, first click it and change the string in the Label text box. At run time, to create a child node, first get a reference to the node that will be used as its parent. One way you can get this reference is to obtain the returned value of the first version of the TreeNodeCollection.Add() method. As its syntax indicates, this method returns a TreeNode object. We have used the default constructor of the TreeNode class and the constructor that takes as argument a string. The TreeNode class provides another constructor whose syntax is: public TreeNode(string text, TreeNode[] children); The first argument of this method is the string that the new node this constructor creates will display. The second argument is a collection of the child nodes of this branch. The collection is passed as an array. Based on this, you use this constructor to create a new node including its children. After creating the new node, you can pass it to the TreeNodeCollection.Add() method as we did earlier. Here is an example: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 280);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 100;
TreeNode[] nodContinents =
{
new TreeNode("Africa"),
new TreeNode("America"),
new TreeNode("Asia"),
new TreeNode("Europe")
};
TreeNode nodWorld = new TreeNode("World", nodContinents);
tvwCountries.Nodes.Add(nodWorld);
Controls.Add(tvwCountries);
}
This would produce
Using the same approach, you can create as many branches and their child nodes as you wish. Here is an example: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 270;
// Create a list of some African countries and
// store them in an array named nodAfricans
TreeNode[] nodAfricans = { new TreeNode("Senegal"),
new TreeNode("Botswana"),
new TreeNode("Ghana"),
new TreeNode("Morocco") };
// Create a list of some American countries and
// store them in an array named nodAmericans
TreeNode[] nodAmericans = { new TreeNode("Canada"),
new TreeNode("Jamaica"),
new TreeNode("Colombia")};
// Create a list of some European countries and
// store them in an array named nodEuropeans
TreeNode[] nodEuropeans = { new TreeNode("Italy"),
new TreeNode("Greece"),
new TreeNode("Spain"),
new TreeNode("England") };
// Create a list of continents, independently
TreeNode nodAfrica = new TreeNode("Africa", nodAfricans);
TreeNode nodAmerica = new TreeNode("America", nodAmericans);
TreeNode nodAsica = new TreeNode("Asia");
TreeNode nodEurope = new TreeNode("Europe", nodEuropeans);
// Store the list of continents in an array named nodContinents
TreeNode[] nodContinents = { nodAfrica, nodAmerica, nodAsica, nodEurope };
// Create a branch named nodWorld and store the list of
// continents as its child
TreeNode nodWorld = new TreeNode("World", nodContinents);
// Finally, add the nodWorld branch to the tree view
tvwCountries.Nodes.Add(nodWorld);
Controls.Add(tvwCountries);
}
This would produce:
The number of nodes in the TreeNode objects is stored in the TreeNodeCollection.Count property. To get the current number of nodes in the tree view, you can call the TreeView.GetNodeCount() method. Its syntax is: public int GetNodeCount(bool includeSubTrees); Here is an example: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 270;
// Create a list of some African countries and
// store them in an array named nodAfricans
TreeNode[] nodAfricans = { new TreeNode("Senegal"),
new TreeNode("Botswana"),
new TreeNode("Ghana"),
new TreeNode("Morocco") };
. . . No Change
Controls.Add(tvwCountries);
int count = tvwCountries.GetNodeCount(true);
Text = count.ToString();
}
This would produce:
If you create a node and add it to a branch that already contains another node, the new node is referred to as a sibling to the existing child node.
In our introduction, we saw that a node, any node, could have as many nodes as you judge necessary. To support this, the TreeNode class is equipped with a property called Nodes, which, like that of the TreeView class, is based on the TreeNodeCollection class. This allows you to refer to the list of children of the node that this Nodes property belongs to. With this information, you can further create or manipulate child nodes of any node as you wish.
Besides looking at a node, probably the primary action a user performs on a tree is to select an item. To select a node in the tree, the user can click it. To programmatically select a node, assign its reference to the TreeView.SelectedNode property. Here is an example: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 100;
TreeNode nodAfrica = new TreeNode("Africa");
TreeNode nodAmerica = new TreeNode("America");
TreeNode nodEurope = new TreeNode("Europe");
TreeNode[] nodContinents = { nodAfrica, nodAmerica, nodEurope };
TreeNode nodWorld = new TreeNode("World", nodContinents);
tvwCountries.Nodes.Add(nodWorld);
tvwCountries.SelectedNode = nodAmerica;
Controls.Add(tvwCountries);
}
After selecting a node, the tree view indicates the item selected by highlighting it. In the following picture, the America node is selected: ![]() To programmatically find out what item is selected in the tree, get the value of the TreeView.SelectedNode Boolean property. If no node is selected, this property produces null. Alternatively, you can check the value of a node's TreeNode.IsSelected Boolean property to find out if it is currently selected.
After locating a node, the user may want to change its text. To change the string of a node, it must be put to edit mode. To do this, you can call the TreeNode.BeginEdit() method. Its syntax is: public void BeginEdit(); When a node is in edit mode, the caret blinks in its edit box section. The user can then type a new string or edit the existing string. After setting the (new) string, the user can press Enter or may click somewhere. At this time, you need to indicate that the user has finished this operation. To do this, you can call the TreeNode.EndEdit() method. Its syntax is: public void EndEdit(bool cancel); Just before this method, you can check the content of the string that was added or edited. This allows you to accept or reject the change. The argument to the EndEdit() method allows you to validate or cancel the editing action.
As mentioned already, the nodes of a tree view are stored in a collection of type TreeNodeCollection. Every time you create a new node, it occupies a position inside the tree. Each node is represented by the Item indexed property of this collection. The first node of the tree has an index of 0. When you call the TreeNodeCollection.Add() method to create a node, the new branch is added at the end of the list of its siblings. If you want, you can add a new child somewhere in the tree. To do this, you would call the TreeNodeCollection.Insert() method. Its syntax is: public virtual void Insert(int index, TreeNode node); The first argument to this method is the index that the new node will occupy when created. The second argument is a reference to the new node to be created. Here is an example of using it: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 100;
TreeNode[] nodContinents =
{
new TreeNode("Africa"),
new TreeNode("America"),
new TreeNode("Asia"),
new TreeNode("Europe")
};
TreeNode nodWorld = new TreeNode("World", nodContinents);
tvwCountries.Nodes.Add(nodWorld);
tvwCountries.Nodes.Insert(1, new TreeNode("Neptune"));
Controls.Add(tvwCountries);
}
This would produce:
Another technique you can use to locate a node consists of using some coordinates. To do this, you can call the TreeView.GetNodeAt() method that is overloaded with two versions whose syntaxes are: public TreeNode GetNodeAt(Point pt); public TreeNode GetNodeAt(int x, int y); To use this method, you must know either the Point location or the x and y coordinates of the node. If you provide valid arguments to this method, it returns a reference to the TreeNode located at the argument. Here is an example: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 100;
TreeNode[] nodContinents =
{
new TreeNode("Africa"),
new TreeNode("America"),
new TreeNode("Asia"),
new TreeNode("Europe")
};
TreeNode nodWorld = new TreeNode("World", nodContinents);
tvwCountries.Nodes.Add(nodWorld);
tvwCountries.ExpandAll();
TreeNode nodBranch = tvwCountries.GetNodeAt(22, 48);
Controls.Add(tvwCountries);
Text = nodBranch.Text;
}
This would produce:
After creating a tree, to get a reference to the first child node, you can retrieve the TreeNode.FirstNode property. You would use code as follows: private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
tvwCountries = new TreeView();
tvwCountries.Location = new Point(12, 12);
tvwCountries.Width = 210;
tvwCountries.Height = 100;
TreeNode[] nodContinents = { new TreeNode("Africa"),
new TreeNode("America"),
new TreeNode("Asia"),
new TreeNode("Europe") };
TreeNode nodWorld = new TreeNode("World", nodContinents);
tvwCountries.Nodes.Add(nodWorld);
TreeNode nodFirst = tvwCountries.Nodes[0].FirstNode;
Controls.Add(tvwCountries);
Text = nodFirst.Text;
}
To get a reference to the last child node, retrieve the TreeNode.LastNode property. You would use code as follows: TreeNode nodLast = tvwCountries.Nodes[0].LastNode; Text = nodLast.Text; To get a reference to the sibling above a node, if any, you can retrieve its TreeNode.PrevNode property. To get a reference to the sibling below a node, if any, you can retrieve its TreeNode.NextNode property. To find whether a tree view contains a certain node, you can call the TreeNodeCollection.Contains() method. Its syntax is: public bool Contains(TreeNode node); This method expects as argument a reference to the node to look for. If the tree contains that node, the method returns true. If the node is not found, this method returns false. |
|
|
private void tvwAutoParts_NodeMouseClick(object sender,
TreeNodeMouseClickEventArgs e)
{
TreeNode nodClicked = e.Node;
if( nodClicked.Level == 4 )
lvwAutoParts.Items.Clear();
try
{
try
{
foreach (PartDescription part in parts)
{
if ((part.Category == nodClicked.Text) &&
(part.Model == nodClicked.Parent.Text) &&
(part.Make == nodClicked.Parent.Parent.Text) &&
(part.CarYear.ToString() == nodClicked.Parent.Parent.Parent.Text))
{
ListViewItem lviAutoPart = new ListViewItem(part.PartNumber.ToString());
lviAutoPart.SubItems.Add(part.PartName);
lviAutoPart.SubItems.Add(part.UnitPrice.ToString());
lvwAutoParts.Items.Add(lviAutoPart);
}
}
}
catch (NullReferenceException)
{
}
}
catch (NullReferenceException)
{
}
}
|
internal void CalculateOrder()
{
// Calculate the current total order and update the order
decimal subTotal1 = 0.00M, subTotal2 = 0.00M, subTotal3 = 0.00M,
subTotal4 = 0.00M, subTotal5 = 0.00M, subTotal6 = 0.00M;
decimal orderTotal = 0.00M;
// Retrieve the value of each sub total
try
{
subTotal1 = decimal.Parse(this.txtSubTotal1.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal2 = decimal.Parse(this.txtSubTotal2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal3 = decimal.Parse(this.txtSubTotal3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal4 = decimal.Parse(this.txtSubTotal4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal5 = decimal.Parse(this.txtSubTotal5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal6 = decimal.Parse(this.txtSubTotal6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
// Calculate the total value of the sub totals
orderTotal = subTotal1 + subTotal2 + subTotal3 +
subTotal4 + subTotal5 + subTotal6;
// Display the total order in the appropriate text box
this.txtTotalOrder.Text = orderTotal.ToString();
}
private void lvwAutoParts_DoubleClick(object sender, EventArgs e)
{
ListViewItem lviAutoPart = lvwAutoParts.SelectedItems[0];
if (lvwAutoParts.SelectedItems.Count == 0 ||
lvwAutoParts.SelectedItems.Count > 1)
return;
if (txtPartNumber1.Text == "")
{
txtPartNumber1.Text = lviAutoPart.Text;
txtPartName1.Text = lviAutoPart.SubItems[1].Text;
txtUnitPrice1.Text = lviAutoPart.SubItems[2].Text;
txtQuantity1.Text = "1";
txtSubTotal1.Text = lviAutoPart.SubItems[2].Text;
txtQuantity1.Focus();
}// If the previous Part # text box is not empty, then use the next one
else if (txtPartNumber2.Text == "")
{
txtPartNumber2.Text = lviAutoPart.Text;
txtPartName2.Text = lviAutoPart.SubItems[1].Text;
txtUnitPrice2.Text = lviAutoPart.SubItems[2].Text;
txtQuantity2.Text = "1";
txtSubTotal2.Text = txtUnitPrice2.Text;
txtQuantity2.Focus();
}
else if (txtPartNumber3.Text == "")
{
txtPartNumber3.Text = lviAutoPart.Text;
txtPartName3.Text = lviAutoPart.SubItems[1].Text;
txtUnitPrice3.Text = lviAutoPart.SubItems[2].Text;
txtQuantity3.Text = "1";
txtSubTotal3.Text = txtUnitPrice3.Text;
txtQuantity3.Focus();
}
else if (txtPartNumber4.Text == "")
{
txtPartNumber4.Text = lviAutoPart.Text;
txtPartName4.Text = lviAutoPart.SubItems[1].Text;
txtUnitPrice4.Text = lviAutoPart.SubItems[2].Text;
txtQuantity4.Text = "1";
txtSubTotal4.Text = txtUnitPrice4.Text;
txtQuantity4.Focus();
}
else if (txtPartNumber5.Text == "")
{
txtPartNumber5.Text = lviAutoPart.Text;
txtPartName5.Text = lviAutoPart.SubItems[1].Text;
txtUnitPrice5.Text = lviAutoPart.SubItems[2].Text;
txtQuantity5.Text = "1";
txtSubTotal5.Text = txtUnitPrice5.Text;
txtQuantity5.Focus();
}
else if (txtPartNumber6.Text == "")
{
txtPartNumber6.Text = lviAutoPart.Text;
txtPartName6.Text = lviAutoPart.SubItems[1].Text;
txtUnitPrice6.Text = lviAutoPart.SubItems[2].Text;
txtQuantity6.Text = "1";
txtSubTotal6.Text = txtUnitPrice6.Text;
txtQuantity6.Focus();
} // If all Part # text boxes are filled, don't do anything
else
return;
CalculateOrder();
}
|
private void txtQuantity1_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
// Get the quantity of the current item
try
{
qty = int.Parse(this.txtQuantity1.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
// Get the unit price of the current item
try
{
unitPrice = decimal.Parse(this.txtUnitPrice1.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
// Calculate the current sub total
subTotal = qty * unitPrice;
// Display the new sub total in the corresponding text box
this.txtSubTotal1.Text = subTotal.ToString();
// Update the order
CalculateOrder();
}
|
private void txtQuantity2_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
subTotal = qty * unitPrice;
this.txtSubTotal2.Text = subTotal.ToString();
CalculateOrder();
}
|
private void txtQuantity3_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
subTotal = qty * unitPrice;
this.txtSubTotal3.Text = subTotal.ToString();
CalculateOrder();
}
|
private void txtQuantity4_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
subTotal = qty * unitPrice;
this.txtSubTotal4.Text = subTotal.ToString();
CalculateOrder();
}
|
private void txtQuantity5_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
subTotal = qty * unitPrice;
this.txtSubTotal5.Text = subTotal.ToString();
CalculateOrder();
}
|
private void txtQuantity6_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
subTotal = qty * unitPrice;
this.txtSubTotal6.Text = subTotal.ToString();
CalculateOrder();
}
|
private void btnRemove1_Click(object sender, EventArgs e)
{
txtPartNumber1.Text = "";
txtPartName1.Text = "";
txtUnitPrice1.Text = "0.00";
txtQuantity1.Text = "0";
txtSubTotal1.Text = "0.00";
CalculateOrder();
}
|
private void btnRemove2_Click(object sender, EventArgs e)
{
txtPartNumber2.Text = "";
txtPartName2.Text = "";
txtUnitPrice2.Text = "0.00";
txtQuantity2.Text = "0";
txtSubTotal2.Text = "0.00";
CalculateOrder();
}
|
private void btnRemove3_Click(object sender, EventArgs e)
{
txtPartNumber3.Text = "";
txtPartName3.Text = "";
txtUnitPrice3.Text = "0.00";
txtQuantity3.Text = "0";
txtSubTotal3.Text = "0.00";
CalculateOrder();
}
|
private void btnRemove4_Click(object sender, EventArgs e)
{
txtPartNumber4.Text = "";
txtPartName4.Text = "";
txtUnitPrice4.Text = "0.00";
txtQuantity4.Text = "0";
txtSubTotal4.Text = "0.00";
CalculateOrder();
}
|
private void btnRemove5_Click(object sender, EventArgs e)
{
txtPartNumber5.Text = "";
txtPartName5.Text = "";
txtUnitPrice5.Text = "0.00";
txtQuantity5.Text = "0";
txtSubTotal5.Text = "0.00";
CalculateOrder();
}
|
private void btnRemove6_Click(object sender, EventArgs e)
{
txtPartNumber6.Text = "";
txtPartName6.Text = "";
txtUnitPrice6.Text = "0.00";
txtQuantity6.Text = "0";
txtSubTotal6.Text = "0.00";
CalculateOrder();
}
|
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
|

|
Deleting Nodes |
|
When a tree contains a few nodes, the user may want to delete some of them, for any reason. To delete a node, you can call the TreeNodeCollection.Remove() method. Its syntax is: public void Remove(TreeNode node); This method expects a reference to the node you want to delete. Another solution you can use would consist of locating the node by its index. To do this, you would call the TreeNodeCollection.RemoveAt() method. Its syntax is: public virtual void RemoveAt(int index); When calling this method, pass the index of the node to be deleted. If you are already at that node and you want to remove it, you can call the TreeNode.Remove() method. Its syntax is: public void Remove(); One of the characteristics of a tree in the real world is that, if you cut a branch, the branches attached to it and their leaves are cut too. In the same way, if you call any of these Remove() or RemoveAt() methods to delete a node, its children, if any, would be deleted too. To remove all nodes of a tree view, you can call the TreeNodeCollection.Clear() method. Its syntax is: public virtual void Clear(); This method is used to get rid of all nodes of a tree. |
|
|
||
| Home | Copyright © 2007-2010 FunctionX, Inc. | Next |
|
|
||