Tree Grid not only allows you to present the data in a structured form but it also supports performing various operations with the nodes. You can add, delete, move and fetch nodes by using various methods provided by the class.

Add Node
You can add a node at a specific position in the Tree Grid using AddNode method of the Node class. This appends a new node row to the collection. The method takes NodeTypeEnum enumeration as its argument which lets you specify a node with respect to another given node.
The code below shows how to add a node in the WinForms Tree Grid at a specific location.
private void cmbAdd_SelectionChangeCommitted(object sender, System.EventArgs e)
{
// Gets current row's node
Node nd = flex.Rows[flex.Row].Node;
// Adds relative as requested by user
// (could be a child or a sibling)
nd.AddNode((NodeTypeEnum)(cmbAdd.SelectedIndex + 2), cmbAdd.Text);
flex.Focus();
}
Private Sub cmbAdd_SelectionChangeCommitted(ByVal sender As Object, ByVal e As EventArgs)
' Gets current row's node
Dim nd As Node = flex.Rows(flex.Row).Node
' Adds relative as requested by user
' (could be a child or a sibling)
nd.AddNode(CType(cmbAdd.SelectedIndex + 2, NodeTypeEnum), cmbAdd.Text)
flex.Focus()
End Sub
Delete Node
You can delete a selected node from the Tree Grid using RemoveNode method of the Node class.
Following code demonstrates how to delete a node from the WinForms Tree Grid.
private void btnDelete_Click(object sender, System.EventArgs e)
{
// Gets current node
Node nd = null;
if ( flex.Rows.Count > 0 && flex.Row >= 0 && flex.Row < flex.Rows.Count)
{
nd = flex.Rows[flex.Row].Node;
}
if (nd != null)
{
// Removes node from FlexGrid
nd.RemoveNode();
flex.Focus();
}
}
Private Sub btnDelete_Click(ByVal sender As Object, ByVal e As EventArgs)
' Gets current node
Dim nd As Node = Nothing
If flex.Rows.Count > 0 AndAlso flex.Row >= 0 AndAlso flex.Row < flex.Rows.Count Then
nd = flex.Rows(flex.Row).Node
End If
If nd IsNot Nothing Then
' Removes node from FlexGrid
nd.RemoveNode()
flex.Focus()
End If
End Sub
Move Node
The Tree Grid allows you to move the node rows to a new position using Move method of the Node class. The method takes NodeMoveEnum enumeration as an argument which lets you specify the direction in which node has to be moved.
Use the code below to move a node of the WinForms Tree Grid to a new position.
private void btnMove_Click(object sender, System.EventArgs e)
{
// Gets current row's node
Node nd = flex.Rows[flex.Row].Node;
// Applies movement selected by the user
// (this will move the selected node)
if (sender == btnMoveOut) nd.Move(NodeMoveEnum.Out);
else if (sender == btnMoveIn) nd.Move(NodeMoveEnum.In);
else if (sender == btnMoveUp) nd.Move(NodeMoveEnum.Up);
else if (sender == btnMoveDown) nd.Move(NodeMoveEnum.Down);
else if (sender == btnMoveFirst) nd.Move(NodeMoveEnum.First);
else if (sender == btnMoveLast) nd.Move(NodeMoveEnum.Last);
// Makes sure the node is still visible
nd.EnsureVisible();
flex.Focus();
}
Private Sub btnMove_Click(ByVal sender As Object, ByVal e As EventArgs)
' Gets current row's node
Dim nd As Node = flex.Rows(flex.Row).Node
' Applies movement selected by the user
' (this will move the selected node)
If sender Is btnMoveOut Then
nd.Move(NodeMoveEnum.Out)
ElseIf sender Is btnMoveIn Then
nd.Move(NodeMoveEnum.[In])
ElseIf sender Is btnMoveUp Then
nd.Move(NodeMoveEnum.Up)
ElseIf sender Is btnMoveDown Then
nd.Move(NodeMoveEnum.Down)
ElseIf sender Is btnMoveFirst Then
nd.Move(NodeMoveEnum.First)
ElseIf sender Is btnMoveLast Then
nd.Move(NodeMoveEnum.Last)
End If
' Makes sure the node is still visible
nd.EnsureVisible()
flex.Focus()
End Sub
Select Nodes
In Tree Grid, you can select the nodes to perform different operations using GetNode method of the Node class. The method takes a parameter called NodeTypeEnum enumeration which specifies a node with respect to another given node.
The code below specifies how to fetch a specific node of the WinForms Tree Grid and show it in selected state.
private void cmbSelect_SelectionChangeCommitted(object sender, System.EventArgs e)
{
// Gets current row's node
Node nd = flex.Rows[flex.Row].Node;
// Gets relative node selected by the user
nd = nd.GetNode((NodeTypeEnum)cmbSelect.SelectedIndex);
// If failed, show message
if (nd == null)
{
MessageBox.Show("Can't find " + cmbSelect.Text + " for this node.");
return;
}
// Selects node and make sure it's visible (by scrolling into view)
nd.Select();
nd.EnsureVisible();
flex.Focus();
}
Private Sub cmbSelect_SelectionChangeCommitted(ByVal sender As Object, ByVal e As EventArgs)
' Gets current row's node
Dim nd As Node = flex.Rows(flex.Row).Node
' Gets relative node selected by the user
nd = nd.GetNode(CType(cmbSelect.SelectedIndex, NodeTypeEnum))
' If failed, show message
If nd Is Nothing Then
MessageBox.Show("Can't find " & cmbSelect.Text & " for this node.")
Return
End If
' Selects node and make sure it's visible (by scrolling into view)
nd.[Select]()
nd.EnsureVisible()
flex.Focus()
End Sub
Expand and Collapse Nodes
You can expand and collapse all nodes in your Tree Grid application using the Collapsed property of Node class as shown in the code below. This feature makes it convenient to navigate through node headers as a group when required.
Following code shows how to expand and collapse nodes of the WinForms Tree Grid.
foreach (Row row in flex.Rows.Cast<Row>().Where(rw => rw.IsNode == true))
{
Node node = row.Node;
node.Collapsed = false;
}
foreach (Row row in flex.Rows.Cast<Row>().Where(rw => rw.IsNode == true))
{
Node node = row.Node;
node.Collapsed = true;
}
For Each row As Row In flex.Rows.Cast(Of Row)().Where(Function(rw) rw.IsNode = True)
Dim node As Node = row.Node
node.Collapsed = False
Next
For Each row As Row In flex.Rows.Cast(Of Row)().Where(Function(rw) rw.IsNode = True)
Dim node As Node = row.Node
node.Collapsed = True
Next
Drag and Drop Nodes
In Tree Grid, you can drag and drop a selected node to a specific position by handling the MouseUp, MouseDown and MouseMove events.
The code below lets the user drag and drop nodes of the WinForms Tree Grid.
private void flex_MouseDown(object sender, MouseEventArgs e)
{
m_DragInfo.checkDrag = false;
// Left button press, no shift: start tracking mouse to drag
if (e.Button != MouseButtons.Left) return;
if (!chkDrag.Checked || m_DragInfo.dragging) return;
if (flex.MouseRow < flex.Rows.Fixed || flex.MouseCol != 0) return;
// Saves current row and mouse position
m_DragInfo.row = flex.Row;
m_DragInfo.mouseDown = new Point(e.X, e.Y);
// Starts checking
m_DragInfo.checkDrag = true;
}
private void flex_MouseMove(object sender, MouseEventArgs e)
{
// If checking and the user moved past our tolerance, start dragging
if (!m_DragInfo.checkDrag || e.Button != MouseButtons.Left) return;
if (Math.Abs(e.X - m_DragInfo.mouseDown.X) +
Math.Abs(e.Y - m_DragInfo.mouseDown.Y) <= DRAGTOL) return;
// Updates flags
m_DragInfo.dragging = true;
// Sets cursor and highlight node
CellStyle cs = flex.Styles["SourceNode"];
flex.Cursor = Cursors.NoMove2D;
flex.SetCellStyle(m_DragInfo.row, 0, cs);
// Checks whether we can drop here
Cursor c = (NoDropHere()) ? Cursors.No : Cursors.NoMove2D;
if (c != flex.Cursor) flex.Cursor = c;
}
private bool NoDropHere()
{
// Row under mouse is not valid
if (flex.MouseRow < flex.Rows.Fixed) return true;
// Column under mouse is not valid
if (flex.MouseCol < flex.Cols.Fixed) return true;
if (flex.GetDataDisplay(flex.Row, 0) == "SKU") return true;
return false;
}
private void flex_MouseUp(object sender, MouseEventArgs e)
{
// We're not checking until the mouse goes down again
m_DragInfo.checkDrag = false;
// Not dragging? we're done
if (!m_DragInfo.dragging) return;
// Stops dragging
m_DragInfo.dragging = false;
flex.SetCellStyle(m_DragInfo.row, 0, (CellStyle)null);
flex.Cursor = Cursors.Default;
// Tests whether the drop is allowed
if (NoDropHere()) return;
// Moves node into new parent node
Node ndSrc = flex.Rows[m_DragInfo.row].Node;
Node ndDst = flex.Rows[flex.Row].Node;
ndSrc.Move(NodeMoveEnum.ChildOf, ndDst);
ndSrc.Select();
}
internal struct DRAGINFO
{
public bool dragging; // Currently dragging
public bool checkDrag; // Currently checking mouse to start dragging
public int row; // Index of row being dragged
public Point mouseDown; // Mouse down position
}
Private Sub flex_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
m_DragInfo.checkDrag = False
' Left button press, no shift: start tracking mouse to drag
If e.Button IsNot MouseButtons.Left Then Return
If Not chkDrag.Checked OrElse m_DragInfo.dragging Then Return
If flex.MouseRow < flex.Rows.Fixed OrElse flex.MouseCol <> 0 Then Return
' Saves current row and mouse position
m_DragInfo.row = flex.Row
m_DragInfo.mouseDown = New Point(e.X, e.Y)
' Starts checking
m_DragInfo.checkDrag = True
End Sub
Private Sub flex_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
' If checking and the user moved past our tolerance, start dragging
If Not m_DragInfo.checkDrag OrElse e.Button IsNot MouseButtons.Left Then Return
If Math.Abs(e.X - m_DragInfo.mouseDown.X) + Math.Abs(e.Y - m_DragInfo.mouseDown.Y) <= DRAGTOL Then Return
' Updates flags
m_DragInfo.dragging = True
' Sets cursor and highlight node
Dim cs As CellStyle = flex.Styles("SourceNode")
flex.Cursor = Cursors.NoMove2D
flex.SetCellStyle(m_DragInfo.row, 0, cs)
' Checks whether we can drop here
Dim c As Cursor = If((NoDropHere()), Cursors.No, Cursors.NoMove2D)
If c IsNot flex.Cursor Then flex.Cursor = c
End Sub
Private Function NoDropHere() As Boolean
' Row under mouse is not valid
If flex.MouseRow < flex.Rows.Fixed Then Return True
' Column under mouse is not valid
If flex.MouseCol < flex.Cols.Fixed Then Return True
If flex.GetDataDisplay(flex.Row, 0) Is "SKU" Then Return True
Return False
End Function
Private Sub flex_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
' We're not checking until the mouse goes down again
m_DragInfo.checkDrag = False
' Not dragging? we're done
If Not m_DragInfo.dragging Then Return
' Stops dragging
m_DragInfo.dragging = False
flex.SetCellStyle(m_DragInfo.row, 0, CType(Nothing, CellStyle))
flex.Cursor = Cursors.[Default]
' Tests whether the drop is allowed
If NoDropHere() Then Return
' Moves node into new parent node
Dim ndSrc As Node = flex.Rows(m_DragInfo.row).Node
Dim ndDst As Node = flex.Rows(flex.Row).Node
ndSrc.Move(NodeMoveEnum.ChildOf, ndDst)
ndSrc.[Select]()
End Sub
Friend Structure DRAGINFO
Public dragging As Boolean ' Currently dragging
Public checkDrag As Boolean ' Currently checking mouse to start dragging
Public row As Integer ' Index of row being dragged
Public mouseDown As Point ' Mouse down position
End Structure