Exemple #1
0
        protected override void OnBeforeSelect(TreeViewCancelEventArgs e)
        {
            base.OnBeforeSelect(e);

            // New selection is always the anchor for the next shift selection
            if (_anchorNode == null || !IsRangeSelect)
            {
                _anchorNode = (TreeNodeMS)e.Node;
            }
        }
Exemple #2
0
        protected override void OnAfterSelect(TreeViewEventArgs e)
        {
            // Save old selection for invalidating
            var selectedNodesOld = SelectedNodes.ToArray();

            TreeNodeMS node = (TreeNodeMS)e.Node;

            // Don't change the selection if this is a right click and the node is in the
            // selection.
            if (node != null && !(_inRightClick && node.IsInSelection))
            {
                if (IsDisjointSelect)
                {
                    // Toggle selection on the node
                    SelectNode(node, !IsNodeSelected(e.Node));
                }
                else if (IsRangeSelect && !ReferenceEquals(_anchorNode, node))
                {
                    // Figure out top and bottom of the range to be selected
                    TreeNodeMS upperNode  = _anchorNode;
                    TreeNodeMS bottomNode = node;
                    if (upperNode.BoundsMS.Top > bottomNode.BoundsMS.Top)
                    {
                        Helpers.Swap(ref upperNode, ref bottomNode);
                    }

                    // Set new selection to contain all visible nodes between top and bottom
                    SelectedNodes.Clear();
                    while (upperNode != null && !ReferenceEquals(upperNode, bottomNode))
                    {
                        SelectNode(upperNode, true);
                        upperNode = (TreeNodeMS)upperNode.NextVisibleNode;
                    }
                    SelectNode(bottomNode, true);
                }
                else
                {
                    // Make this a single selection of the selected node.
                    SelectedNodes.Clear();
                    SelectNode(node, true);
                }

                // Invalidate the changed nodes
                var unchangedNodes = new HashSet <TreeNodeMS>(selectedNodesOld.Intersect(SelectedNodes));
                InvalidateChangedNodes(selectedNodesOld, unchangedNodes);
                InvalidateChangedNodes(SelectedNodes, unchangedNodes);
            }

            Invalidate();

            // Make sure selection is updated before after select event is fired
            base.OnAfterSelect(e);
        }
Exemple #3
0
 protected override void OnMouseDown(MouseEventArgs e)
 {
     _inRightClick = e.Button == MouseButtons.Right;
     if (_inRightClick)
     {
         TreeNodeMS node = (TreeNodeMS)GetNodeAt(0, e.Y);
         if (node != null && node.BoundsMS.Contains(e.Location))
         {
             SelectedNode = node;
         }
     }
     base.OnMouseDown(e);
 }
Exemple #4
0
 public void SelectNode(TreeNodeMS node, bool select)
 {
     if (!select)
     {
         SelectedNodes.Remove(node);
     }
     else if (!node.IsInSelection)
     {
         SelectedNodes.Add(node);
         // Make sure all ancestors of this node are expanded
         for (var parent = node.Parent; parent != null && !parent.IsExpanded; parent = parent.Parent)
         {
             parent.Expand();
         }
     }
     node.IsInSelection = select;
 }
Exemple #5
0
        protected void UpdateSelection()
        {
            // Remove any nodes from the selection that may have been
            // removed from the tree.
            var selectedNodes = SelectedNodes.ToArray();

            foreach (var node in selectedNodes)
            {
                if (node.TreeView == null)
                {
                    SelectedNodes.Remove(node);
                }
            }

            // If any nodes were removed from the selection, reset the
            // anchor node to the selected node.
            if (selectedNodes.Length != SelectedNodes.Count)
            {
                _anchorNode = (TreeNodeMS)SelectedNode;
            }
        }
Exemple #6
0
 protected override void OnMouseUp(MouseEventArgs e)
 {
     if (!_inRightClick)
     {
         TreeNodeMS node = (TreeNodeMS)GetNodeAt(0, e.Y);
         if (node != null && node.BoundsMS.Contains(e.Location))
         {
             // If we are within the bounds of a node and that node is not the selected node,
             // make it the selected node. Changing the font of the TreeView at runtime
             // apparently does not update node bounds, so we need to do this check in case the
             // user clicked outside of the original node bounds.
             if (!ReferenceEquals(node, SelectedNode))
             {
                 SelectedNode = node;
             }
             // Handle cases where clicking on the selected node should change
             // the selection.
             else
             {
                 // Disjoint selection or the SelectedNode is not in the selection
                 if (IsDisjointSelect || !IsNodeSelected(node))
                 {
                     SelectedNode = null;
                 }
                 // More than a single node currently selected, and not performing
                 // range selection on an existing range selection.
                 else if (SelectedNodes.Count > 1 &&
                          (!IsRangeSelect || ReferenceEquals(_anchorNode, SelectedNode)))
                 {
                     SelectedNode = null;
                 }
             }
         }
     }
     base.OnMouseUp(e);
     _inRightClick = false;
 }
Exemple #7
0
        public virtual void DrawNodeCustom(Graphics g, int rightEdge)
        {
            EnsureWidthCustom(g);

            Rectangle bounds = BoundsMS;

            // Draw dashed lines
            var treeView  = TreeViewMS;
            var dashBrush = treeView.DashBrush;

            // Horizontal line.
            dashBrush.TranslateTransform(Level % 2 + HorizScrollDiff, 0);
            g.FillRectangle(dashBrush, XIndent, bounds.Top + bounds.Height / 2,
                            TreeViewMS.HORZ_DASH_LENGTH, 1);
            // Vertical lines corresponding to the horizontal level of this node.
            dashBrush.TranslateTransform(-Level % 2 - HorizScrollDiff, 0);
            // Check if this is the Root.
            if (ReferenceEquals(this, treeView.Nodes[0]))
            {
                if (treeView.Nodes.Count > 1)
                {
                    g.FillRectangle(dashBrush, XIndent, bounds.Top + bounds.Height / 2,
                                    1, bounds.Height / 2);
                }
            }
            // Move up the levels of the tree, drawing the corresponding vertical lines.
            else
            {
                try
                {
                    TreeNodeMS curNode = this;
                    while (curNode != null)
                    {
                        dashBrush.TranslateTransform(0, curNode.Level % 2);
                        if (curNode.NextNode != null)
                        {
                            g.FillRectangle(dashBrush, curNode.XIndent, bounds.Top, 1, bounds.Height);
                        }
                        else if (curNode == this)
                        {
                            g.FillRectangle(dashBrush, curNode.XIndent, bounds.Top, 1, bounds.Height / 2);
                        }
                        dashBrush.TranslateTransform(0, -curNode.Level % 2);
                        curNode = curNode.Parent as TreeNodeMS;
                    }
                }
                catch (NullReferenceException)
                {
                    // Ignore a NullReferenceException in this code.  The case
                    // that once caused this has been fixed, but this safeguard is
                    // kept to avoid showing an unhandled exception to the user.

                    // If the node being painted is in the process of being removed
                    // from the tree, then curNode.NextNode will throw a NRE.
                }
            }

            // Draw Collapse/Expand bmps and the image associated with the node.
            if (Nodes.Count > 0)
            {
                Image expandCollapse = IsExpanded ? Resources.Collapse : Resources.Expand;
                g.DrawImage(expandCollapse, XIndent - expandCollapse.Width / 2,
                            bounds.Top + (BoundsMS.Height - expandCollapse.Height + 1) / 2);
            }

            // Draw images associated with the node.
            int       imgLocX = XIndent + TreeViewMS.HORZ_DASH_LENGTH;
            const int imgWidth = TreeViewMS.IMG_WIDTH, imgHeight = TreeViewMS.IMG_WIDTH;

            if (StateImageIndex != -1)
            {
                Image stateImg = TreeView.StateImageList.Images[StateImageIndex];
                g.DrawImageUnscaled(stateImg, imgLocX, bounds.Top + (bounds.Height - imgHeight) / 2, imgWidth, imgHeight);
                imgLocX += imgWidth;
            }
            if (ImageIndex != -1)
            {
                Image nodeImg = TreeView.ImageList.Images[ImageIndex];
                g.DrawImageUnscaled(nodeImg, imgLocX, bounds.Top + (bounds.Height - imgHeight) / 2, imgWidth, imgHeight);
            }

            DrawTextMS(g);
        }
Exemple #8
0
 protected void InvalidateNode(TreeNodeMS node)
 {
     Invalidate(new Rectangle(0, node.BoundsMS.Top, ClientRectangle.Width, node.BoundsMS.Height));
 }