/// Disposes the entire selection manager. internal void Dispose() { // We've got to be careful here. We're one of the last things to go away when // a form is being torn down, and we've got to be wary if things have pulled out // already. host.RemoveService(typeof(ISelectionService)); host.TransactionOpened -= new EventHandler(this.DesignerHost_TransactionOpened); host.TransactionClosed -= new DesignerTransactionCloseEventHandler(this.DesignerHost_TransactionClosed); if (host.InTransaction) { DesignerHost_TransactionClosed(host, new DesignerTransactionCloseEventArgs(true)); } host.LoadComplete -= new EventHandler(this.DesignerHost_LoadComplete); IComponentChangeService cs = (IComponentChangeService)host.GetService(typeof(IComponentChangeService)); if (cs != null) { cs.ComponentAdded -= new ComponentEventHandler(this.DesignerHost_ComponentAdd); cs.ComponentRemoved -= new ComponentEventHandler(this.DesignerHost_ComponentRemove); cs.ComponentChanged -= new ComponentChangedEventHandler(this.DesignerHost_ComponentChanged); } EtoSelectionItem[] sels = new EtoSelectionItem[selectionsByComponent.Values.Count]; selectionsByComponent.Values.CopyTo(sels, 0); for (int i = 0; i < sels.Length; i++) { sels[i].Dispose(); } selectionsByComponent.Clear(); primarySelection = null; }
/// Sets the given selection object to be the primary selection. internal void SetPrimarySelection(EtoSelectionItem sel) { if (sel != primarySelection) { if (null != primarySelection) { primarySelection.Primary = false; } primarySelection = sel; } if (null != primarySelection) { primarySelection.Primary = true; } }
/// Removes the given selection from our selection list private void RemoveSelection(EtoSelectionItem s) { selectionsByComponent.Remove(s.Component); s.Dispose(); }
/// Called by the formcore when someone has removed a component. This will /// remove any selection on the component without disturbing the rest of /// the selection. private void DesignerHost_ComponentRemove(object sender, ComponentEventArgs ce) { EtoSelectionItem sel = (EtoSelectionItem)selectionsByComponent[ce.Component]; if (sel != null) { RemoveSelection(sel); // If we removed the last selection and we have a designer host, then select the base // component of the host. Otherwise, it is OK to have an empty selection. if (selectionsByComponent.Count == 0 && host != null) { // Now we have to run through all the components and pick // the control with the highest z-order. IComponent[] comps = new IComponent[host.Container.Components.Count]; host.Container.Components.CopyTo(comps, 0); if (comps == null) { return; } int maxZOrder = -1; int defaultIndex = -1; object maxIndexComp = null; object baseComp = host.RootComponent; if (baseComp == null) { return; } for (int i = comps.Length - 1; i >= 0; i--) { if (comps[i] == baseComp) { continue; } else if (defaultIndex == -1) { defaultIndex = i; } if (comps[i] is Control) { int zorder = ((Control)comps[i]).TabIndex; if (zorder > maxZOrder) { maxZOrder = zorder; maxIndexComp = (object)comps[i]; } } } if (maxIndexComp == null) { if (defaultIndex != -1) { maxIndexComp = comps[defaultIndex]; } else { maxIndexComp = baseComp; } } ((ISelectionService)this).SetSelectedComponents(new object[] { maxIndexComp }, SelectionTypes.Replace); } else { OnSelectionChanged(); } } else { // Component isn't selected, but our list of selectable components is // different. OnSelectionContentsChanged(); } }
/// Adds the given selection to our selection list. private void AddSelection(EtoSelectionItem sel) { selectionsByComponent[sel.Component] = sel; }
/// Select the given components with the given SelectionType. void ISelectionService.SetSelectedComponents(ICollection components, SelectionTypes selectionType) { bool fToggle = false; bool fControl = false; bool fClick = false; bool fChanged = false; // did we actually change something? // Catch a null input list if (components == null) { components = new Component[0]; } if ((selectionType & SelectionTypes.Normal) == SelectionTypes.Normal || (selectionType & SelectionTypes.Click) == SelectionTypes.Click) { fControl = ((Control.ModifierKeys & Keys.Control) == Keys.Control); // Only toggle when we are affecting a single control, and // when we are handling the "mouse" state events (i.e. up/down // used to show/hide the selection). // fToggle = ((Control.ModifierKeys & Keys.Control) != 0 || (Control.ModifierKeys & Keys.Shift) != 0) && components.Count == 1 && (selectionType & SelectionTypes.MouseUp) != SelectionTypes.MouseUp; } if ((selectionType & SelectionTypes.Click) == SelectionTypes.Click) { fClick = true; } // If we are replacing the selection, only remove the ones that are not in our new list. // We also handle the special case here of having a singular component selected that's // already selected. In this case we just move it to the primary selection. // if (!fToggle && !fControl) { object firstSelection = null; foreach (object o in components) { firstSelection = o; break; } if (fClick && 1 == components.Count && ((ISelectionService)this).GetComponentSelected(firstSelection)) { EtoSelectionItem oldPrimary = primarySelection; SetPrimarySelection((EtoSelectionItem)selectionsByComponent[firstSelection]); if (oldPrimary != primarySelection) { fChanged = true; } } else { EtoSelectionItem[] selections = new EtoSelectionItem[selectionsByComponent.Values.Count]; selectionsByComponent.Values.CopyTo(selections, 0); // Even with several hundred components this should be fairly fast foreach (EtoSelectionItem item in selections) { bool remove = true; foreach (object comp in components) { if (comp == item.Component) { remove = false; break; } } if (remove) { RemoveSelection(item); fChanged = true; } } } } EtoSelectionItem primarySel = null; int selectedCount = selectionsByComponent.Count; // Now do the selection. foreach (Component comp in components) { if (comp != null) { EtoSelectionItem s = (EtoSelectionItem)selectionsByComponent[comp]; if (null == s) { s = new EtoSelectionItem(this, comp); AddSelection(s); if (fControl || fToggle) { primarySel = s; } fChanged = true; } else { if (fToggle) { // Remove the selection from our list. RemoveSelection(s); fChanged = true; } } } } if (primarySel != null) { SetPrimarySelection(primarySel); } // Now notify that our selection has changed if (fChanged) { OnSelectionChanged(); } }