/// <summary> /// Handles keyboard shortcuts. /// </summary> /// <param name="e"></param> protected override void OnKeyDown(KeyEventArgs e) { e.Handled = e.SuppressKeyPress = true; if (e.Alt && (e.KeyCode == Keys.Down)) { DroppedDown = true; } else if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Left)) { ComboTreeNode prev = GetPrevDisplayedNode(); if (prev != null) { SetSelectedNode(prev); } } else if ((e.KeyCode == Keys.Down) || (e.KeyCode == Keys.Right)) { ComboTreeNode next = GetNextDisplayedNode(); if (next != null) { SetSelectedNode(next); } } else { e.Handled = e.SuppressKeyPress = false; } base.OnKeyDown(e); }
/// <summary> /// Sets the value of the SelectedNode property and raises the SelectedNodeChanged event. /// </summary> /// <param name="node"></param> private void SetSelectedNode(ComboTreeNode node) { if (selectedNode != node) { selectedNode = node; Invalidate(); OnSelectedNodeChanged(EventArgs.Empty); } }
/// <summary> /// Determines whether the specified node belongs to this ComboTreeBox, and /// hence is a valid selection. For the purposes of this method, a null /// value is always a valid selection. /// </summary> /// <param name="node"></param> /// <returns></returns> private bool OwnsNode(ComboTreeNode node) { if (node == null) { return(true); } ComboTreeNode parent = node; while (parent.Parent != null) { parent = parent.Parent; } return(nodes.Contains(parent)); }
/// <summary> /// Determines whether the specified node should be displayed. /// </summary> /// <param name="node"></param> /// <returns></returns> internal bool IsNodeVisible(ComboTreeNode node) { bool displayed = true; ComboTreeNode parent = node; while ((parent = parent.Parent) != null) { if (!parent.Expanded) { displayed = false; break; } } return(displayed); }
/// <summary> /// Returns the image referenced by the specified node in the ImageList component associated with this control. /// </summary> /// <param name="node"></param> /// <returns></returns> internal Image GetNodeImage(ComboTreeNode node) { if ((images != null) && (node != null)) { if (node.Expanded) { if (images.Images.ContainsKey(node.ExpandedImageKey)) { return(images.Images[node.ExpandedImageKey]); // node's key } else if (node.ExpandedImageIndex >= 0) { return(images.Images[node.ExpandedImageIndex]); // node's index } else if (images.Images.ContainsKey(expandedImageKey)) { return(images.Images[expandedImageKey]); // default key } else if (expandedImageIndex >= 0) { return(images.Images[expandedImageIndex]); // default index } } else { if (images.Images.ContainsKey(node.ImageKey)) { return(images.Images[node.ImageKey]); // node's key } else if (node.ImageIndex >= 0) { return(images.Images[node.ImageIndex]); // node's index } else if (images.Images.ContainsKey(imageKey)) { return(images.Images[imageKey]); // default key } else if (imageIndex >= 0) { return(images.Images[imageIndex]); // default index } } } return(null); }
/// <summary> /// Displays the dropdown beneath its owning ComboTreeBox control. /// </summary> public void Open() { if (sourceControl.SelectedNode != null) { ComboTreeNode node = sourceControl.SelectedNode; // the selected node must have a clear path (i.e. all parents expanded) while ((node = node.Parent) != null) { node.Expanded = true; } } UpdateVisibleItems(); // highlight and scroll to the selected node if (sourceControl.SelectedNode != null) { for (int i = 0; i < visibleItems.Count; i++) { if (visibleItems[i].Node == sourceControl.SelectedNode) { highlightedItemIndex = i; if ((highlightedItemIndex < scrollOffset) || (highlightedItemIndex >= (scrollOffset + numItemsDisplayed))) { scrollOffset = Math.Min(Math.Max(0, highlightedItemIndex - numItemsDisplayed + 1), visibleItems.Count - numItemsDisplayed); UpdateScrolling(); } break; } } } // show below the source control Show(sourceControl, new Point(0, sourceControl.ClientRectangle.Height - 1)); }
/// <summary> /// Determines all of the parameters for drawing the bitmap beside the /// specified node. If they represent a unique combination, the bitmap is /// generated and returned. Otherwise, the appropriate cached bitmap is /// returned. /// </summary> /// <param name="node"></param> /// <returns></returns> private Image GetItemBitmap(ComboTreeNode node) { BitmapInfo bitmapInfo = new BitmapInfo(); // the following factors determine the bitmap drawn: ComboTreeNodeCollection collection = GetCollectionContainingNode(node); bitmapInfo.HasChildren = (node.Nodes.Count > 0); bitmapInfo.IsLastPeer = (collection.IndexOf(node) == (collection.Count - 1)); bitmapInfo.IsFirst = (node == sourceControl.Nodes[0]); bitmapInfo.NodeDepth = node.Depth; bitmapInfo.NodeExpanded = node.Expanded && bitmapInfo.HasChildren; bitmapInfo.ImageIndex = bitmapInfo.NodeExpanded ? node.ExpandedImageIndex : node.ImageIndex; bitmapInfo.ImageKey = bitmapInfo.NodeExpanded ? node.ExpandedImageKey : node.ImageKey; bitmapInfo.VerticalLines = new bool[bitmapInfo.NodeDepth]; ComboTreeNode parent = node; int i = 0; while ((parent = parent.Parent) != null) { // vertical line required if parent is expanded (and not last peer) ComboTreeNodeCollection parentCollection = GetCollectionContainingNode(parent); bitmapInfo.VerticalLines[i] = (parent.Expanded && (parentCollection.IndexOf(parent) != (parentCollection.Count - 1))); i++; } if (bitmaps.ContainsKey(bitmapInfo)) { return(bitmaps[bitmapInfo]); } else { return(bitmaps[bitmapInfo] = GenerateBitmap(bitmapInfo, sourceControl.GetNodeImage(node))); } }
/// <summary> /// Scrolls between adjacent nodes, or scrolls the drop-down portion of /// the control in response to the mouse wheel. /// </summary> /// <param name="e"></param> protected override void OnMouseWheel(MouseEventArgs e) { base.OnMouseWheel(e); if (DroppedDown) { dropDown.ScrollDropDown(-(e.Delta / 120) * SystemInformation.MouseWheelScrollLines); } else if (e.Delta > 0) { ComboTreeNode prev = GetPrevDisplayedNode(); if (prev != null) { SetSelectedNode(prev); } } else if (e.Delta < 0) { ComboTreeNode next = GetNextDisplayedNode(); if (next != null) { SetSelectedNode(next); } } }
/// <summary> /// Returns the ComboTreeNodeCollection to which the specified node belongs. /// </summary> /// <param name="node"></param> /// <returns></returns> private ComboTreeNodeCollection GetCollectionContainingNode(ComboTreeNode node) { return((node.Parent != null) ? node.Parent.Nodes : sourceControl.Nodes); }
/// <summary> /// Creates a new instance of the NodeInfo class to represent the /// specified ComboTreeNode. /// </summary> /// <param name="node"></param> public NodeInfo(ComboTreeNode node) { Node = node; }