| File: System\Windows\Forms\Design\BaseContextMenuStrip.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj (System.Windows.Forms.Design) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; namespace System.Windows.Forms.Design; /// <summary> /// This class is going to replace the shell contextMenu and uses the ContextMenuStrip. /// The ContextMenuStrip contains groups and groupOrder which it uses to add items to itself. /// ControlDesigners can add custom items to the contextMenu, using the new member to the /// group and add the groupOrder to the ContextMenu. /// </summary> internal class BaseContextMenuStrip : GroupedContextMenuStrip { private readonly IServiceProvider _serviceProvider; private ToolStripMenuItem? _selectionMenuItem; public BaseContextMenuStrip(IServiceProvider provider) : base() { _serviceProvider = provider; // Now initialize the contextMenu InitializeContextMenu(); } /// <summary> /// Helper function to add the "View Code" menuItem. /// </summary> private void AddCodeMenuItem() { StandardCommandToolStripMenuItem codeMenuItem = new(StandardCommands.ViewCode, SR.ContextMenuViewCode, "viewcode", _serviceProvider); Groups[StandardGroups.Code].Items.Add(codeMenuItem); } /// <summary> /// Helper function to add the "SendToBack/BringToFront" menuItem. /// </summary> private void AddZorderMenuItem() { StandardCommandToolStripMenuItem ZOrderMenuItem = new(StandardCommands.BringToFront, SR.ContextMenuBringToFront, "bringToFront", _serviceProvider); Groups[StandardGroups.ZORder].Items.Add(ZOrderMenuItem); ZOrderMenuItem = new StandardCommandToolStripMenuItem(StandardCommands.SendToBack, SR.ContextMenuSendToBack, "sendToBack", _serviceProvider); Groups[StandardGroups.ZORder].Items.Add(ZOrderMenuItem); } /// <summary> /// Helper function to add the "Alignment" menuItem. /// </summary> private void AddGridMenuItem() { StandardCommandToolStripMenuItem gridMenuItem = new(StandardCommands.AlignToGrid, SR.ContextMenuAlignToGrid, "alignToGrid", _serviceProvider); Groups[StandardGroups.Grid].Items.Add(gridMenuItem); } /// <summary> /// Helper function to add the "Locked" menuItem. /// </summary> private void AddLockMenuItem() { StandardCommandToolStripMenuItem lockMenuItem = new(StandardCommands.LockControls, SR.ContextMenuLockControls, "lockControls", _serviceProvider); Groups[StandardGroups.Lock].Items.Add(lockMenuItem); } /// <summary> /// Helper function to add the Select Parent menuItem. /// </summary> private void RefreshSelectionMenuItem() { int index = -1; if (_selectionMenuItem is not null) { index = Items.IndexOf(_selectionMenuItem); Groups[StandardGroups.Selection].Items.Remove(_selectionMenuItem); Items.Remove(_selectionMenuItem); } List<Component> parentControls = []; int nParentControls = 0; // Get the currently selected Control if (_serviceProvider.GetService(typeof(ISelectionService)) is ISelectionService selectionService && _serviceProvider.GetService(typeof(IDesignerHost)) is IDesignerHost host) { IComponent root = host.RootComponent; Debug.Assert(root is not null, "Null root component. Will be unable to build selection menu"); if (selectionService.PrimarySelection is Control selectedControl && root is not null && selectedControl != root) { Control? parentControl = selectedControl.Parent; while (parentControl is not null) { if (parentControl.Site is not null) { parentControls.Add(parentControl); nParentControls++; } if (parentControl == root) { break; } parentControl = parentControl.Parent; } } else if (selectionService.PrimarySelection is ToolStripItem selectedItem) { if (host.GetDesigner(selectedItem) is ToolStripItemDesigner itemDesigner) { parentControls = itemDesigner.AddParentTree(); nParentControls = parentControls.Count; } } } if (nParentControls > 0) { _selectionMenuItem = new ToolStripMenuItem(); if (_serviceProvider.GetService(typeof(IUIService)) is IUIService uis) { _selectionMenuItem.DropDown.Renderer = (ToolStripProfessionalRenderer)uis.Styles["VsRenderer"]!; // Set the right Font _selectionMenuItem.DropDown.Font = (Font)uis.Styles["DialogFont"]!; if (uis.Styles["VsColorPanelText"] is Color color) { _selectionMenuItem.DropDown.ForeColor = color; } } _selectionMenuItem.Text = SR.ContextMenuSelect; foreach (Component parent in parentControls) { ToolStripMenuItem selectListItem = new SelectToolStripMenuItem(parent, _serviceProvider); _selectionMenuItem.DropDownItems.Add(selectListItem); } Groups[StandardGroups.Selection].Items.Add(_selectionMenuItem); // Re-add the newly refreshed item. if (index != -1) { Items.Insert(index, _selectionMenuItem); } } } /// <summary> /// Helper function to add the Verbs. /// </summary> private void AddVerbMenuItem() { // Add Designer Verbs.. if (_serviceProvider.TryGetService(out IMenuCommandService? menuCommandService)) { DesignerVerbCollection verbCollection = menuCommandService.Verbs; foreach (DesignerVerb verb in verbCollection) { DesignerVerbToolStripMenuItem verbItem = new(verb); Groups[StandardGroups.Verbs].Items.Add(verbItem); } } } /// <summary> /// Helper function to add the "Cut/Copy/Paste/Delete" menuItem. /// </summary> private void AddEditMenuItem() { StandardCommandToolStripMenuItem stdMenuItem = new(StandardCommands.Cut, SR.ContextMenuCut, "cut", _serviceProvider); Groups[StandardGroups.Edit].Items.Add(stdMenuItem); stdMenuItem = new StandardCommandToolStripMenuItem(StandardCommands.Copy, SR.ContextMenuCopy, "copy", _serviceProvider); Groups[StandardGroups.Edit].Items.Add(stdMenuItem); stdMenuItem = new StandardCommandToolStripMenuItem(StandardCommands.Paste, SR.ContextMenuPaste, "paste", _serviceProvider); Groups[StandardGroups.Edit].Items.Add(stdMenuItem); stdMenuItem = new StandardCommandToolStripMenuItem(StandardCommands.Delete, SR.ContextMenuDelete, "delete", _serviceProvider); Groups[StandardGroups.Edit].Items.Add(stdMenuItem); } /// <summary> /// Helper function to add the "Properties" menuItem. /// </summary> private void AddPropertiesMenuItem() { StandardCommandToolStripMenuItem stdMenuItem = new(StandardCommands.DocumentOutline, SR.ContextMenuDocumentOutline, "", _serviceProvider); Groups[StandardGroups.Properties].Items.Add(stdMenuItem); stdMenuItem = new StandardCommandToolStripMenuItem(MenuCommands.DesignerProperties, SR.ContextMenuProperties, "properties", _serviceProvider); Groups[StandardGroups.Properties].Items.Add(stdMenuItem); } /// <summary> /// Basic Initialize method. /// </summary> private void InitializeContextMenu() { Name = "designerContextMenuStrip"; if (_serviceProvider.TryGetService(out IUIService? uis)) { Renderer = (ToolStripProfessionalRenderer)uis.Styles["VsRenderer"]!; if (uis.Styles["VsColorPanelText"] is Color color) { ForeColor = color; } } GroupOrdering.AddRange([ StandardGroups.Code, StandardGroups.ZORder, StandardGroups.Grid, StandardGroups.Lock, StandardGroups.Verbs, StandardGroups.Custom, StandardGroups.Selection, StandardGroups.Edit, StandardGroups.Properties]); // ADD MENUITEMS AddCodeMenuItem(); AddZorderMenuItem(); AddGridMenuItem(); AddLockMenuItem(); AddVerbMenuItem(); RefreshSelectionMenuItem(); AddEditMenuItem(); AddPropertiesMenuItem(); } /// <summary> /// Public function that allows the individual MenuItems to get refreshed each time the ContextMenu is opened. /// </summary> public override void RefreshItems() { if (_serviceProvider.TryGetService(out IUIService? uis)) { Font = (Font)uis.Styles["DialogFont"]!; } foreach (ToolStripItem item in Items) { if (item is StandardCommandToolStripMenuItem stdItem) { stdItem.RefreshItem(); } } RefreshSelectionMenuItem(); } /// <summary> /// A ToolStripMenuItem that gets added for the "Select" menuitem. /// </summary> private class SelectToolStripMenuItem : ToolStripMenuItem { private readonly Component? _comp; private readonly IServiceProvider _serviceProvider; private readonly Type _itemType; private bool _cachedImage; private Image? _image; private static readonly string s_systemWindowsFormsNamespace = typeof(ToolStripItem).Namespace!; public SelectToolStripMenuItem(Component c, IServiceProvider provider) { _comp = c; _serviceProvider = provider; // Get NestedSiteName... string? compName = null; if (_comp is not null && _comp.Site is { } site) { if (site is INestedSite nestedSite && !string.IsNullOrEmpty(nestedSite.FullName)) { compName = nestedSite.FullName; } else if (!string.IsNullOrEmpty(site.Name)) { compName = site.Name; } } Text = string.Format(SR.ToolStripSelectMenuItem, compName); _itemType = c.GetType(); } public override Image? Image { get { // Defer loading the image until we're sure we need it if (!_cachedImage) { _cachedImage = true; // else attempt to get the resource from a known place in the manifest. // if and only if the namespace of the type is System.Windows.Forms. // else attempt to get the resource from a known place in the manifest if (_itemType.Namespace == s_systemWindowsFormsNamespace) { _image = ToolboxBitmapAttribute.GetImageFromResource(_itemType, imageName: null, large: false); } // if all else fails, throw up a default image. _image ??= ToolboxBitmapAttribute.GetImageFromResource(_comp!.GetType(), imageName: null, large: false); } return _image; } set { _image = value; _cachedImage = true; } } /// <summary> /// Items OnClick event, to select the Parent Control. /// </summary> protected override void OnClick(EventArgs e) { if (_comp is not null && _serviceProvider.TryGetService(out ISelectionService? selectionService)) { selectionService.SetSelectedComponents(new object[] { _comp }, SelectionTypes.Replace); } } } }