[]
        
(Showing Draft Content)

Node Operations

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 Node class.


Node operations

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](gcdocsite__documentlink?toc-item-id=f7337334-ecfb-4c0e-abec-c9fef5f1e33c)
    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](gcdocsite__documentlink?toc-item-id=f7337334-ecfb-4c0e-abec-c9fef5f1e33c)
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