Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / CompMod / System / ComponentModel / Design / MenuCommandService.cs / 1 / MenuCommandService.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.ComponentModel.Design { using Microsoft.Win32; using System; using System.Design; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System.Globalization; using IServiceProvider = System.IServiceProvider; ////// /// The menu command service allows designers to add and respond to /// menu and toolbar items. It is based on two interfaces. Designers /// request IMenuCommandService to add menu command handlers, while /// the document or tool window forwards IOleCommandTarget requests /// to this object. /// public class MenuCommandService : IMenuCommandService, IDisposable { private IServiceProvider _serviceProvider; private Hashtable _commandGroups; private EventHandler _commandChangedHandler; private MenuCommandsChangedEventHandler _commandsChangedHandler; private ArrayList _globalVerbs; private ISelectionService _selectionService; internal static TraceSwitch MENUSERVICE = new TraceSwitch("MENUSERVICE", "MenuCommandService: Track menu command routing"); // This is the set of verbs we offer through the Verbs property. // It consists of the global verbs + any verbs that the currently // selected designer wants to offer. This collection changes with the // current selection. // private DesignerVerbCollection _currentVerbs; // this is the type that we last picked up verbs from // so we know when we need to refresh // private Type _verbSourceType; ////// /// Creates a new menu command service. /// public MenuCommandService(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; _commandGroups = new Hashtable(); _commandChangedHandler = new EventHandler(this.OnCommandChanged); TypeDescriptor.Refreshed += new RefreshEventHandler(this.OnTypeRefreshed); } ////// /// This event is thrown whenever a MenuCommand is removed /// or added /// public event MenuCommandsChangedEventHandler MenuCommandsChanged { add { _commandsChangedHandler += value; } remove { _commandsChangedHandler -= value; } } ////// /// Retrieves a set of verbs that are global to all objects on the design /// surface. This set of verbs will be merged with individual component verbs. /// In the case of a name conflict, the component verb will NativeMethods. /// public virtual DesignerVerbCollection Verbs { get { EnsureVerbs(); return _currentVerbs; } } ////// /// Adds a menu command to the document. The menu command must already exist /// on a menu; this merely adds a handler for it. /// public virtual void AddCommand(MenuCommand command) { if (command == null) { throw new ArgumentNullException("command"); } // If the command already exists, it is an error to add // a duplicate. // if (((IMenuCommandService)this).FindCommand(command.CommandID) != null) { throw new ArgumentException(SR.GetString(SR.MenuCommandService_DuplicateCommand, command.CommandID.ToString())); } ArrayList commandsList = _commandGroups[command.CommandID.Guid] as ArrayList; if (null == commandsList) { commandsList = new ArrayList(); commandsList.Add(command); _commandGroups.Add(command.CommandID.Guid, commandsList); } else { commandsList.Add(command); } command.CommandChanged += _commandChangedHandler; Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "Command added: " + command.ToString()); //fire event OnCommandsChanged(new MenuCommandsChangedEventArgs(MenuCommandsChangedType.CommandAdded, command)); } ////// /// Adds a verb to the set of global verbs. Individual components should /// use the Verbs property of their designer, rather than call this method. /// This method is intended for objects that want to offer a verb that is /// available regardless of what components are selected. /// public virtual void AddVerb(DesignerVerb verb) { if (verb == null) { throw new ArgumentNullException("verb"); } if (_globalVerbs == null) { _globalVerbs = new ArrayList(); } _globalVerbs.Add(verb); OnCommandsChanged(new MenuCommandsChangedEventArgs(MenuCommandsChangedType.CommandAdded, verb)); EnsureVerbs(); if (!((IMenuCommandService)this).Verbs.Contains(verb)) { ((IMenuCommandService)this).Verbs.Add(verb); } /* */ } ////// /// Disposes of this service. /// public void Dispose() { Dispose(true); } ////// /// Disposes of this service. /// protected virtual void Dispose(bool disposing) { if (disposing) { if (_selectionService != null) { _selectionService.SelectionChanging -= new EventHandler(this.OnSelectionChanging); _selectionService = null; } if (_serviceProvider != null) { _serviceProvider = null; TypeDescriptor.Refreshed -= new RefreshEventHandler(this.OnTypeRefreshed); } IDictionaryEnumerator groupsEnum = _commandGroups.GetEnumerator(); while(groupsEnum.MoveNext()) { ArrayList commands = (ArrayList)groupsEnum.Value; foreach(MenuCommand command in commands) { command.CommandChanged -= _commandChangedHandler; } commands.Clear(); } } } ////// /// Ensures that the verb list has been created. /// protected void EnsureVerbs() { // We apply global verbs only if the base component is the // currently selected object. // bool useGlobalVerbs = false; if (_currentVerbs == null && _serviceProvider != null) { Hashtable buildVerbs = null; ArrayList verbsOrder; if (_selectionService == null) { _selectionService = GetService(typeof(ISelectionService)) as ISelectionService; if (_selectionService != null) { _selectionService.SelectionChanging += new EventHandler(this.OnSelectionChanging); } } int verbCount = 0; DesignerVerbCollection localVerbs = null; DesignerVerbCollection designerActionVerbs = new DesignerVerbCollection(); // we instanciate this one here... IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost; if (_selectionService != null && designerHost != null && _selectionService.SelectionCount == 1) { object selectedComponent = _selectionService.PrimarySelection; if (selectedComponent is IComponent && !TypeDescriptor.GetAttributes(selectedComponent).Contains(InheritanceAttribute.InheritedReadOnly)) { useGlobalVerbs = (selectedComponent == designerHost.RootComponent); // LOCAL VERBS IDesigner designer = designerHost.GetDesigner((IComponent)selectedComponent); if (designer != null) { localVerbs = designer.Verbs; if (localVerbs != null) { verbCount += localVerbs.Count; _verbSourceType = selectedComponent.GetType(); } else { _verbSourceType = null; } } // DesignerAction Verbs DesignerActionService daSvc = GetService(typeof(DesignerActionService)) as DesignerActionService; if(daSvc != null) { DesignerActionListCollection actionLists = daSvc.GetComponentActions(selectedComponent as IComponent); if(actionLists != null) { foreach(DesignerActionList list in actionLists) { DesignerActionItemCollection dai = list.GetSortedActionItems(); if(dai != null) { for(int i = 0; i< dai.Count; i++ ) { DesignerActionMethodItem dami = dai[i] as DesignerActionMethodItem; if(dami != null && dami.IncludeAsDesignerVerb) { EventHandler handler = new EventHandler(dami.Invoke); DesignerVerb verb = new DesignerVerb(dami.DisplayName, handler); designerActionVerbs.Add(verb); verbCount++; } } } } } } } } // GLOBAL VERBS if (useGlobalVerbs && _globalVerbs == null) { useGlobalVerbs = false; } if (useGlobalVerbs) { verbCount += _globalVerbs.Count; } // merge all buildVerbs = new Hashtable(verbCount, StringComparer.OrdinalIgnoreCase); verbsOrder = new ArrayList(verbCount); // PRIORITY ORDER FROM HIGH TO LOW: LOCAL VERBS - DESIGNERACTION VERBS - GLOBAL VERBS if (useGlobalVerbs) { for(int i=0;i<_globalVerbs.Count;i++) { string key = ((DesignerVerb)_globalVerbs[i]).Text; buildVerbs[key] = verbsOrder.Add(_globalVerbs[i]); } } if(designerActionVerbs.Count > 0) { for(int i=0;i0) { for(int i=0;i /// /// Searches for the given command ID and returns the MenuCommand /// associated with it. /// public MenuCommand FindCommand(CommandID commandID) { return FindCommand(commandID.Guid, commandID.ID); } ////// /// Locates the requested command. This will throw an appropriate /// ComFailException if the command couldn't be found. /// protected MenuCommand FindCommand(Guid guid, int id) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "MCS Searching for command: " + guid.ToString() + " : " + id.ToString(CultureInfo.CurrentCulture)); // Search in the list of commands only if the command group is known ArrayList commands = _commandGroups[guid] as ArrayList; if(null != commands) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t...MCS Found group"); foreach(MenuCommand command in commands) { if(command.CommandID.ID == id) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t... MCS Found Command"); return command; } } } // Next, search the verb list as well. // EnsureVerbs(); if (_currentVerbs != null) { int currentID = StandardCommands.VerbFirst.ID; foreach (DesignerVerb verb in _currentVerbs) { CommandID cid = verb.CommandID; if (cid.ID == id) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t...MCS Found verb"); if (cid.Guid.Equals(guid)) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t...MCS Found group"); return verb; } } // We assign virtual sequential IDs to verbs we get from the component. This allows users // to not worry about assigning these IDs themselves. // if (currentID == id) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t...MCS Found verb"); if (cid.Guid.Equals(guid)) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t...MCS Found group"); return verb; } } if (cid.Equals(StandardCommands.VerbFirst)) currentID++; } } return null; } ////// /// Get the command list for a given GUID /// protected ICollection GetCommandList(Guid guid) { return (_commandGroups[guid] as ArrayList); } ////// /// protected object GetService(Type serviceType) { if (serviceType == null) { throw new ArgumentNullException("serviceType"); } if (_serviceProvider != null) { return _serviceProvider.GetService(serviceType); } return null; } ////// /// Invokes a command on the local form or in the global environment. /// The local form is first searched for the given command ID. If it is /// found, it is invoked. Otherwise the the command ID is passed to the /// global environment command handler, if one is available. /// public virtual bool GlobalInvoke(CommandID commandID) { // try to find it locally MenuCommand cmd = ((IMenuCommandService)this).FindCommand(commandID); if (cmd != null) { cmd.Invoke(); return true; } return false; } ////// /// Invokes a command on the local form or in the global environment. /// The local form is first searched for the given command ID. If it is /// found, it is invoked. Otherwise the the command ID is passed to the /// global environment command handler, if one is available. /// public virtual bool GlobalInvoke(CommandID commandId, object arg) { // try to find it locally MenuCommand cmd = ((IMenuCommandService)this).FindCommand(commandId); if (cmd != null) { cmd.Invoke(arg); return true; } return false; } ////// /// This is called by a menu command when it's status has changed. /// private void OnCommandChanged(object sender, EventArgs e) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "Command dirty: " + ((sender != null) ? sender.ToString() : "(null sender)" )); OnCommandsChanged(new MenuCommandsChangedEventArgs(MenuCommandsChangedType.CommandChanged, (MenuCommand)sender)); } ////// /// /// protected virtual void OnCommandsChanged(MenuCommandsChangedEventArgs e) { if (_commandsChangedHandler != null) { _commandsChangedHandler(this, e); } } ////// /// Called by TypeDescriptor when a type changes. If this type is currently holding /// our verb, invalidate the list. /// private void OnTypeRefreshed(RefreshEventArgs e) { if (_verbSourceType != null && _verbSourceType.IsAssignableFrom(e.TypeChanged)) { _currentVerbs = null; } } ////// /// This is called by the selection service when the selection has changed. Here /// we invalidate our verb list. /// private void OnSelectionChanging(object sender, EventArgs e) { if (_currentVerbs != null) { _currentVerbs = null; OnCommandsChanged(new MenuCommandsChangedEventArgs(MenuCommandsChangedType.CommandChanged, null)); } } ////// /// Removes the given menu command from the document. /// public virtual void RemoveCommand(MenuCommand command) { if (command == null) { throw new ArgumentNullException("command"); } ArrayList commands = _commandGroups[command.CommandID.Guid] as ArrayList; if (null != commands) { int index = commands.IndexOf(command); if (-1 != index) { commands.RemoveAt(index); // If there are no more commands in this command group, remove the group if (commands.Count == 0) { _commandGroups.Remove(command.CommandID.Guid); } command.CommandChanged -= _commandChangedHandler; Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "Command removed: " + command.ToString()); //fire event OnCommandsChanged(new MenuCommandsChangedEventArgs(MenuCommandsChangedType.CommandRemoved, command)); } return; } Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "Unable to remove command: " + command.ToString()); } ////// /// Removes the given verb from the document. /// public virtual void RemoveVerb(DesignerVerb verb) { if (verb == null) { throw new ArgumentNullException("verb"); } if (_globalVerbs != null) { int index = _globalVerbs.IndexOf(verb); if (index != -1) { _globalVerbs.RemoveAt(index); EnsureVerbs(); if (((IMenuCommandService)this).Verbs.Contains(verb)) { ((IMenuCommandService)this).Verbs.Remove(verb); } OnCommandsChanged(new MenuCommandsChangedEventArgs(MenuCommandsChangedType.CommandRemoved, verb)); } } /* */ } ////// /// Shows the context menu with the given command ID at the given /// location. /// public virtual void ShowContextMenu(CommandID menuID, int x, int y) { } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DockPattern.cs
- DaylightTime.cs
- AbstractDataSvcMapFileLoader.cs
- ContentOperations.cs
- SqlProcedureAttribute.cs
- OptimizedTemplateContentHelper.cs
- CharEnumerator.cs
- RsaKeyIdentifierClause.cs
- HtmlWindow.cs
- DocumentPageHost.cs
- TransformGroup.cs
- PropertyValueUIItem.cs
- SqlBulkCopyColumnMapping.cs
- Utility.cs
- DeploymentSection.cs
- wgx_commands.cs
- LineGeometry.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- PropertyEmitterBase.cs
- UdpDiscoveryEndpoint.cs
- DataTrigger.cs
- PromptStyle.cs
- EntityContainerRelationshipSetEnd.cs
- ProfileService.cs
- GeometryGroup.cs
- ActiveDocumentEvent.cs
- DataSourceCache.cs
- OleDbRowUpdatingEvent.cs
- CultureTable.cs
- SortExpressionBuilder.cs
- mediapermission.cs
- sqlcontext.cs
- ListBoxItemWrapperAutomationPeer.cs
- SiteOfOriginPart.cs
- GeneralTransform3D.cs
- Color.cs
- SimpleWorkerRequest.cs
- ToolStripManager.cs
- BufferBuilder.cs
- HttpModulesSection.cs
- PropertyTabAttribute.cs
- CacheForPrimitiveTypes.cs
- CapabilitiesAssignment.cs
- RawKeyboardInputReport.cs
- ToolBarOverflowPanel.cs
- ActiveXHost.cs
- BuildProvidersCompiler.cs
- XmlElementAttribute.cs
- AxisAngleRotation3D.cs
- SignedPkcs7.cs
- ToolboxComponentsCreatedEventArgs.cs
- WindowsSlider.cs
- ObjectQueryState.cs
- ResolveNameEventArgs.cs
- ClientClassGenerator.cs
- PolyBezierSegment.cs
- MetadataItem_Static.cs
- WindowsGraphicsWrapper.cs
- CompModHelpers.cs
- ColumnMapCopier.cs
- ProcessHostConfigUtils.cs
- PropertyGridView.cs
- XPathBinder.cs
- SqlDependencyListener.cs
- ArithmeticException.cs
- OdbcHandle.cs
- SecurityAccessDeniedException.cs
- QueryAsyncResult.cs
- IteratorDescriptor.cs
- InputProviderSite.cs
- HTMLTextWriter.cs
- DropSource.cs
- ExpressionEditorAttribute.cs
- TextTreeText.cs
- CompilerTypeWithParams.cs
- BackgroundFormatInfo.cs
- DecoderReplacementFallback.cs
- SamlSubjectStatement.cs
- GridItemCollection.cs
- COM2ExtendedBrowsingHandler.cs
- WebBrowserUriTypeConverter.cs
- SafeReadContext.cs
- SessionPageStatePersister.cs
- DbMetaDataColumnNames.cs
- Context.cs
- DefaultAutoFieldGenerator.cs
- nulltextnavigator.cs
- COM2IProvidePropertyBuilderHandler.cs
- shaperfactoryquerycacheentry.cs
- SamlConditions.cs
- IPAddressCollection.cs
- PropertyToken.cs
- FixedNode.cs
- HashSetEqualityComparer.cs
- Merger.cs
- LinkButton.cs
- EventLogInternal.cs
- LabelEditEvent.cs
- HandlerFactoryWrapper.cs
- ImageMap.cs