/// <summary> /// Creates a new instance of the MultiSourceTreeView. /// </summary> public MultiSourceTreeView() { MoveNodesOnDragDrop = false; BeforeExpand += MultiSourceTreeView_BeforeExpand; AfterSelect += MultiSourceTreeView_AfterSelect; MouseDown += MultiSourceTreeView_MouseDown; SortMode = SortMode.NodeSource; Paint += MultiSourceTreeView_Paint; SortMode = SortMode.Alphabetical; DragOverNode += MultiSourceTreeView_DragOverNode; NodeDropped += MultiSourceTreeView_NodeDropped; MouseEnter += MultiSourceTreeView_MouseEnter; MouseLeave += MultiSourceTreeView_MouseLeave; MouseMove += new MouseEventHandler(MultiSourceTreeView_MouseMove); popupMenu = new ButtonItem(); popupMenu.AutoExpandOnClick = true; cmbPopupMenu = new ContextMenuBar(); cmbPopupMenu.Name = "PopupMenuBar"; cmbPopupMenu.BeginInit(); cmbPopupMenu.Items.Add(popupMenu); cmbPopupMenu.Style = eDotNetBarStyle.Office2007; Controls.Add(cmbPopupMenu); cmbPopupMenu.EndInit(); mouseIdle.SynchronizingObject = this; mouseIdle.Elapsed += new System.Timers.ElapsedEventHandler(mouseIdle_Elapsed); tooltip.CheckTooltipPosition = false; AfterLabelEdit += new NodeLabelEditEventHandler(MultiSourceTreeView_AfterLabelEdit); BeforeLabelEdit += new NodeLabelEditEventHandler(MultiSourceTreeView_BeforeLabelEdit); NodeMouseClick += new TreeNodeMouseClickEventHandler(MultiSourceTreeView_NodeMouseClick); GotFocus += new EventHandler(MultiSourceTreeView_GotFocus); }
protected void UpdateContextMenu(MultiSourceTreeNode[] nodes) { cmbPopupMenu.BeginInit(); // Clear the existing menu items, killing their tooltip in the process - otherwise // there would be a dangling reference and they would never go out of scope. foreach (BaseItem item in popupMenu.SubItems) { tooltip.SetSuperTooltip(item, null); } popupMenu.SubItems.Clear(); // We need some nodez biatches! if (nodes.Length == 0) { return; } Dictionary <MenuGroup, Dictionary <string, ButtonItem> > items = new Dictionary <MenuGroup, Dictionary <string, ButtonItem> >(); // Get a sorted list of groups and their child items. foreach (MultiSourceTreeNode node in nodes) { foreach (NodeInfo info in node.InfoEntries) { foreach (NodeStateSubscriber subscriber in info.Subscriptions) { if (!subscriber.Active) { continue; } // Copy the menu definitions to a temp array so they can be sorted. MenuDefinition[] defs = new MenuDefinition[subscriber.State.MenuDefinitions.Count]; subscriber.State.MenuDefinitions.Keys.CopyTo(defs, 0); Array.Sort(defs, new MenuDefinitionComparer()); foreach (MenuDefinition def in defs) { // If we have a test, run it to see if this item should be added. if (def.MenuItemTest != null) { if (!def.MenuItemTest.Invoke(node, info)) { continue; // Nope! } } // Get the group container. Dictionary <string, ButtonItem> container; if (!items.ContainsKey(def.Group)) { items.Add(def.Group, new Dictionary <string, ButtonItem>()); } container = items[def.Group]; // Create and add the menu item. ButtonItem menuItem = def.CreateMenuItem(node, tooltip); menuItem.Tag = info; // TODO: This will need to be adjusted to the plural text somehow // if more than one node is selected that contains this type. if (!container.ContainsKey(def.Text)) { container.Add(def.Text, menuItem); } } } } } // Return if we had no groups to display. if (items.Count == 0) { return; } // Now that we have all of our groups, we need to sort them by priority. List <ButtonItemGroup> sortedGroups = new List <ButtonItemGroup>(); while (items.Count > 0) { MenuGroup priorityGroup = null; foreach (MenuGroup group in items.Keys) { if (priorityGroup == null) { priorityGroup = group; } else if (group.SortingPriority > priorityGroup.SortingPriority) { priorityGroup = group; } } ButtonItem[] buttonItems = new ButtonItem[items[priorityGroup].Values.Count]; items[priorityGroup].Values.CopyTo(buttonItems, 0); ButtonItemGroup newGroup = new ButtonItemGroup(); newGroup.Group = priorityGroup; newGroup.Items = buttonItems; sortedGroups.Add(newGroup); items.Remove(priorityGroup); } // And now we can construct the actual popup menu! YAY! foreach (ButtonItemGroup group in sortedGroups) { LabelItem groupLabel = group.Group.CreateLabelItem(); popupMenu.SubItems.Add(groupLabel); popupMenu.SubItems.AddRange(group.Items); } // Final pass - remove incorrect grouping. for (int x = 0; x < popupMenu.SubItems.Count; x++) { if (x == 0) { popupMenu.SubItems[x].BeginGroup = false; } else { if (!(popupMenu.SubItems[x - 1] is ButtonItem)) { popupMenu.SubItems[x].BeginGroup = false; } } } cmbPopupMenu.EndInit(); }