| File: System\Windows\Forms\Design\TemplateNodeCustomMenuItemCollection.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. #nullable disable using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; namespace System.Windows.Forms.Design; /// <summary> /// Custom ContextMenu section for ToolStripMenuItems. /// </summary> internal class TemplateNodeCustomMenuItemCollection : CustomMenuItemCollection { private readonly ToolStripItem _currentItem; private readonly IServiceProvider _serviceProvider; private ToolStripMenuItem _insertToolStripMenuItem; public TemplateNodeCustomMenuItemCollection(IServiceProvider provider, Component currentItem) : base() { _serviceProvider = provider; _currentItem = currentItem as ToolStripItem; PopulateList(); } /// <summary> /// Immediate parent - can be ToolStrip if the Item is on the toplevel /// </summary> private ToolStrip ParentTool { get => _currentItem.Owner; } private void PopulateList() { _insertToolStripMenuItem = new ToolStripMenuItem { Text = SR.ToolStripItemContextMenuInsert, DropDown = ToolStripDesignerUtils.GetNewItemDropDown(ParentTool, _currentItem, new EventHandler(AddNewItemClick), false, _serviceProvider, true) }; Add(_insertToolStripMenuItem); } private void AddNewItemClick(object sender, EventArgs e) { ItemTypeToolStripMenuItem senderItem = (ItemTypeToolStripMenuItem)sender; Type t = senderItem.ItemType; // we are inserting a new item.. InsertItem(t); } private void InsertItem(Type t) { InsertToolStripItem(t); } /// <summary> /// Insert Item into ToolStrip. /// </summary> // Standard 'catch all - rethrow critical' exception pattern private void InsertToolStripItem(Type t) { IDesignerHost designerHost = (IDesignerHost)_serviceProvider.GetService(typeof(IDesignerHost)); Debug.Assert(designerHost is not null, "Why didn't we get a designer host?"); ToolStrip parent = ParentTool; int dummyIndex = parent.Items.IndexOf(_currentItem); DesignerTransaction newItemTransaction = designerHost.CreateTransaction(SR.ToolStripAddingItem); try { // turn off Adding/Added events listened to by the ToolStripDesigner... ToolStripDesigner.s_autoAddNewItems = false; // the code in ComponentAdded will actually get the add done. IComponent component = designerHost.CreateComponent(t); IDesigner designer = designerHost.GetDesigner(component); if (designer is ComponentDesigner componentDesigner) { componentDesigner.InitializeNewComponent(null); } // Set the Image property and DisplayStyle... if (component is ToolStripButton or ToolStripSplitButton or ToolStripDropDownButton) { Image image = null; try { image = new Icon(typeof(ToolStripButton), "blank").ToBitmap(); } catch (Exception e) when (!e.IsCriticalException()) { } PropertyDescriptor imageProperty = TypeDescriptor.GetProperties(component)["Image"]; Debug.Assert(imageProperty is not null, "Could not find 'Image' property in ToolStripItem."); if (imageProperty is not null && image is not null) { imageProperty.SetValue(component, image); } PropertyDescriptor dispProperty = TypeDescriptor.GetProperties(component)["DisplayStyle"]; Debug.Assert(dispProperty is not null, "Could not find 'DisplayStyle' property in ToolStripItem."); dispProperty?.SetValue(component, ToolStripItemDisplayStyle.Image); PropertyDescriptor imageTransProperty = TypeDescriptor.GetProperties(component)["ImageTransparentColor"]; Debug.Assert(imageTransProperty is not null, "Could not find 'DisplayStyle' property in ToolStripItem."); imageTransProperty?.SetValue(component, Color.Magenta); } Debug.Assert(dummyIndex != -1, "Why is the index of the Item negative?"); parent.Items.Insert(dummyIndex, (ToolStripItem)component); // set the selection to our new item.. since we destroyed Original component.. we have to ask SelectionService from new Component ISelectionService selSvc = (ISelectionService)_serviceProvider.GetService(typeof(ISelectionService)); selSvc?.SetSelectedComponents(new object[] { component }, SelectionTypes.Replace); } catch (Exception ex) { newItemTransaction?.Cancel(); newItemTransaction = null; if (ex.IsCriticalException()) { throw; } } finally { newItemTransaction?.Commit(); // turn off Adding/Added events listened to by the ToolStripDesigner... ToolStripDesigner.s_autoAddNewItems = true; // Add the glyphs if the parent is DropDown. if (parent is ToolStripDropDown parentDropDown && parentDropDown.Visible) { if (parentDropDown.OwnerItem is ToolStripDropDownItem ownerItem) { if (designerHost.GetDesigner(ownerItem) is ToolStripMenuItemDesigner itemDesigner) { itemDesigner.ResetGlyphs(ownerItem); } } } } } }