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;i 0) {
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
- NamedPermissionSet.cs
- Descriptor.cs
- SingleStorage.cs
- EDesignUtil.cs
- Registry.cs
- ObjectComplexPropertyMapping.cs
- ClientBuildManager.cs
- RewritingPass.cs
- Content.cs
- CodeConditionStatement.cs
- JsonQueryStringConverter.cs
- XmlSchemaDatatype.cs
- CatalogZone.cs
- ExtentCqlBlock.cs
- StrokeNodeEnumerator.cs
- MultidimensionalArrayItemReference.cs
- ProgressBarBrushConverter.cs
- DataGridViewHitTestInfo.cs
- SoapMessage.cs
- mediaeventargs.cs
- DataGridViewCellParsingEventArgs.cs
- TableLayoutColumnStyleCollection.cs
- CopyNodeSetAction.cs
- ToolboxItemFilterAttribute.cs
- ContentFileHelper.cs
- EventsTab.cs
- HtmlControl.cs
- StringPropertyBuilder.cs
- HierarchicalDataSourceControl.cs
- BitStream.cs
- DataGridTextBoxColumn.cs
- PathSegment.cs
- ActivityInterfaces.cs
- ObjectDataSourceSelectingEventArgs.cs
- storepermission.cs
- BaseTemplateCodeDomTreeGenerator.cs
- MessageQueueInstaller.cs
- Helper.cs
- StdRegProviderWrapper.cs
- CodeStatementCollection.cs
- InkCanvasInnerCanvas.cs
- BulletedListEventArgs.cs
- ProxyGenerator.cs
- GroupItem.cs
- AndCondition.cs
- ColorAnimationBase.cs
- ServicePointManager.cs
- ListViewItem.cs
- RoutedEventValueSerializer.cs
- ErrorEventArgs.cs
- InvalidOleVariantTypeException.cs
- SystemIcmpV6Statistics.cs
- ReadContentAsBinaryHelper.cs
- RecommendedAsConfigurableAttribute.cs
- LayoutSettings.cs
- ParseElementCollection.cs
- XsltInput.cs
- EditorZone.cs
- PixelFormatConverter.cs
- EditorZone.cs
- MdImport.cs
- HtmlControlPersistable.cs
- QuaternionAnimation.cs
- DataRelationCollection.cs
- InitializationEventAttribute.cs
- fixedPageContentExtractor.cs
- SafeNativeMethodsOther.cs
- Solver.cs
- MatrixTransform3D.cs
- X509AsymmetricSecurityKey.cs
- EntityContainer.cs
- LifetimeServices.cs
- AudioDeviceOut.cs
- ComplexObject.cs
- SerializationFieldInfo.cs
- XmlTextWriter.cs
- DrawingAttributes.cs
- SourceFilter.cs
- ConfigWriter.cs
- Label.cs
- ToolStripPanelRenderEventArgs.cs
- Context.cs
- XmlSchemaNotation.cs
- InstanceContextMode.cs
- sqlstateclientmanager.cs
- DataViewManagerListItemTypeDescriptor.cs
- TablePatternIdentifiers.cs
- AnimationClockResource.cs
- MenuItem.cs
- InfoCardCryptoHelper.cs
- ProxyElement.cs
- PolyLineSegmentFigureLogic.cs
- StorageFunctionMapping.cs
- SqlAliasesReferenced.cs
- UnmanagedMemoryStream.cs
- RtfToXamlLexer.cs
- XmlDataDocument.cs
- QilStrConcat.cs
- DataGridViewCellValidatingEventArgs.cs
- ArrayList.cs