diff --git a/src/System.Design/src/System.Design.Forwards.cs b/src/System.Design/src/System.Design.Forwards.cs index a36c7c11be3..f2905f6b951 100644 --- a/src/System.Design/src/System.Design.Forwards.cs +++ b/src/System.Design/src/System.Design.Forwards.cs @@ -81,6 +81,7 @@ [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.ToolStripMenuItemDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.TrackBarDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.TreeViewDesigner))] +[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.ToolStripCollectionEditor))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.UpDownBaseDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.UserControlDocumentDesigner))] diff --git a/src/System.Windows.Forms.Design/src/Resources/SR.resx b/src/System.Windows.Forms.Design/src/Resources/SR.resx index 189892d8d15..1ff3988b4b2 100644 --- a/src/System.Windows.Forms.Design/src/Resources/SR.resx +++ b/src/System.Windows.Forms.Design/src/Resources/SR.resx @@ -1476,6 +1476,12 @@ Press Ctrl+Enter to accept Text. TableLayoutPanel cannot expand to contain the control, because the panel's GrowStyle property is set to 'FixedSize'. + + (&None) + + + (&Multiple Items) + Opens the Images collection editor diff --git a/src/System.Windows.Forms.Design/src/Resources/System/WinForms/Design/BlankToolstrip.bmp b/src/System.Windows.Forms.Design/src/Resources/System/WinForms/Design/BlankToolstrip.bmp new file mode 100644 index 00000000000..3788cf1e87e Binary files /dev/null and b/src/System.Windows.Forms.Design/src/Resources/System/WinForms/Design/BlankToolstrip.bmp differ diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.cs.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.cs.xlf index 77fd803b2d9..9298f3c8b39 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.cs.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.cs.xlf @@ -2332,6 +2332,16 @@ Stisknutím kombinace kláves Ctrl+Enter text přijměte. Vložení třídy MenuItem prvku ToolStrip v transakci prvku DropDown + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Upravit položky... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.de.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.de.xlf index b51861be88c..17bc9da74a6 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.de.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.de.xlf @@ -2332,6 +2332,16 @@ Drücken Sie STRG+EINGABETASTE, um Text zu übernehmen. "ToolStrip MenuItem Insert" in DropDown-Transaktion. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... Einträge &bearbeiten... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.es.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.es.xlf index e26bb16d7dd..d5bc259e7e8 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.es.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.es.xlf @@ -2332,6 +2332,16 @@ Presione Ctrl+Entrar para aceptar el texto. Inserción de MenuItem de ToolStrip en transacción DropDown. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Editar elementos... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.fr.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.fr.xlf index 0877bf6b61b..32eddbc9003 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.fr.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.fr.xlf @@ -2332,6 +2332,16 @@ Appuyez sur Ctrl+Entrée pour valider le texte. Transaction Insertion d'un MenuItem ToolStrip dans DropDown. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Modifier les éléments... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.it.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.it.xlf index 095f10d87b7..7ad3cc86c98 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.it.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.it.xlf @@ -2332,6 +2332,16 @@ Per accettare testo premere CTRL+INVIO. Inserisci elemento MenuItem di un controllo ToolStrip in transazione DropDown + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Modifica elementi... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ja.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ja.xlf index 324f9f64a17..3cd6ef705be 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ja.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ja.xlf @@ -2332,6 +2332,16 @@ Press Ctrl+Enter to accept Text. DropDown での ToolStrip MenuItem の挿入トランザクションです。 + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... 項目の編集(&E)... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ko.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ko.xlf index c2c50494d2c..bd5462043ce 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ko.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ko.xlf @@ -2332,6 +2332,16 @@ Press Ctrl+Enter to accept Text. DropDown 트랜잭션의 ToolStrip MenuItem 삽입입니다. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... 항목 편집(&E)... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pl.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pl.xlf index 6c21ff24aa1..871106fd044 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pl.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pl.xlf @@ -2332,6 +2332,16 @@ Naciśnij klawisze Ctrl+Enter, aby zaakceptować tekst. Operacja ToolStrip MenuItem Insert w DropDown. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Edytuj elementy... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pt-BR.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pt-BR.xlf index 5e68b54cc33..e3aec7eadd4 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pt-BR.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.pt-BR.xlf @@ -2332,6 +2332,16 @@ Pressione Ctrl+Enter para aceitar Texto. Inserção de ToolStrip MenuItem na Transação DropDown. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Editar Itens... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ru.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ru.xlf index c30a933cb51..ed82a0938f3 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ru.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.ru.xlf @@ -2332,6 +2332,16 @@ Press Ctrl+Enter to accept Text. Вставка элементов меню ToolStrip в транзакцию DropDown. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Правка элементов… diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.tr.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.tr.xlf index aae519a3e45..d7095490bae 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.tr.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.tr.xlf @@ -2332,6 +2332,16 @@ Metni kabul etmek için Ctrl+Enter tuşlarına basın. DropDown İşleminde ToolStrip MenuItem Ekleme. + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... &Öğeleri Düzenle... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hans.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hans.xlf index 8fa9d2b9ee0..c8c4d5dbd47 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hans.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hans.xlf @@ -2332,6 +2332,16 @@ Press Ctrl+Enter to accept Text. DropDown 事务中的“ToolStrip 菜单项插入”。 + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... 编辑项(&E)... diff --git a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hant.xlf b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hant.xlf index f8695a54e27..f851232ba62 100644 --- a/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hant.xlf +++ b/src/System.Windows.Forms.Design/src/Resources/xlf/SR.zh-Hant.xlf @@ -2332,6 +2332,16 @@ Press Ctrl+Enter to accept Text. DropDown 異動中的 ToolStrip MenuItem 插入。 + + (&Multiple Items) + (&Multiple Items) + + + + (&None) + (&None) + + &Edit Items... 編輯項目(&E)... diff --git a/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj b/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj index 74ac5d4b609..d90c206de40 100644 --- a/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj +++ b/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj @@ -52,6 +52,10 @@ System.ComponentModel.Design + + ToolStripCollectionEditor.ToolStripItemEditorForm.cs + System.Windows.Forms.Design + colordlg.data @@ -73,7 +77,7 @@ - + @@ -92,7 +96,7 @@ System.Windows.Forms.Design.Behavior.%(FileName) - + True diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCollectionEditor.ToolStripItemEditorForm.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCollectionEditor.ToolStripItemEditorForm.cs new file mode 100644 index 00000000000..2437d9c70f4 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCollectionEditor.ToolStripItemEditorForm.cs @@ -0,0 +1,1296 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; + +#nullable disable + +namespace System.Windows.Forms.Design; + +internal partial class ToolStripCollectionEditor +{ + /// + /// Our internal form UI for the . + /// + protected class ToolStripItemEditorForm : CollectionForm + { + private readonly ToolStripCollectionEditor _editor; + private const int ICON_DIMENSION = 16; + private const int SEPARATOR_HEIGHT = 4; + private const int TEXT_IMAGE_SPACING = 6; + private const int INDENT_SPACING = 4; + private const int IMAGE_PADDING = 1; + + private static bool s_isScalingInitialized; + private static int s_iconHeight = ICON_DIMENSION; + private static int s_iconWidth = ICON_DIMENSION; + private static int s_separatorHeight = SEPARATOR_HEIGHT; + private static int s_textImageSpacing = TEXT_IMAGE_SPACING; + private static int s_indentSpacing = INDENT_SPACING; + private static int s_imagePaddingX = IMAGE_PADDING; + private static int s_imagePaddingY = IMAGE_PADDING; + + private ToolStripCustomTypeDescriptor _toolStripCustomTypeDescriptor; + + /// + /// The amount of space we use when GDI+ returns us a string length. + /// + private const int GdiPlusExtraSpace = 5; + + /// + /// The collection we're actually editing. + /// + private ToolStripItemCollection _targetToolStripCollection; + + /// + /// Our list of items that we're editing. + /// + private EditorItemCollection _itemList; + + /// + /// The start index of custom items in the new item type dropdown. + /// + private int _customItemIndex = -1; + + /// + /// All our control instance variables. + /// + private TableLayoutPanel _tableLayoutPanel; + private TableLayoutPanel _addTableLayoutPanel; + private TableLayoutPanel _okCancelTableLayoutPanel; + private Button _btnCancel; + private Button _btnOK; + private Button _btnMoveUp; + private Button _btnMoveDown; + private Label _lblItems; + private ImageComboBox _newItemTypes; + private Button _btnAddNew; + private FilterListBox _listBoxItems; + private Label _selectedItemName; + private Button _btnRemove; + private VsPropertyGrid _selectedItemProps; + private Label _lblMembers; + + private IComponentChangeService _componentChangeSvc; + private readonly string _originalText; + + /// + /// Create the form and set it up. + /// + /// The collection editor that spawned us. + internal ToolStripItemEditorForm(CollectionEditor parent) : base(parent) + { + if (!s_isScalingInitialized) + { + if (ScaleHelper.IsScalingRequired) + { + s_iconHeight = LogicalToDeviceUnits(ICON_DIMENSION); + s_iconWidth = LogicalToDeviceUnits(ICON_DIMENSION); + s_separatorHeight = LogicalToDeviceUnits(SEPARATOR_HEIGHT); + s_textImageSpacing = LogicalToDeviceUnits(TEXT_IMAGE_SPACING); + s_indentSpacing = LogicalToDeviceUnits(INDENT_SPACING); + s_imagePaddingX = LogicalToDeviceUnits(IMAGE_PADDING); + s_imagePaddingY = LogicalToDeviceUnits(IMAGE_PADDING); + } + + s_isScalingInitialized = true; + } + + _editor = (ToolStripCollectionEditor)parent; + InitializeComponent(); + if (ScaleHelper.IsScalingRequired) + { + ScaleButtonImageLogicalToDevice(_btnMoveUp); + ScaleButtonImageLogicalToDevice(_btnMoveDown); + ScaleButtonImageLogicalToDevice(_btnRemove); + } + + ActiveControl = _listBoxItems; + _originalText = Text; + SetStyle(ControlStyles.ResizeRedraw, true); + } + + /// + /// The collection that we're editing. Setting this causes us to sync our contents with that collection. + /// + internal ToolStripItemCollection Collection + { + set + { + if (value != _targetToolStripCollection) + { + // Clear our existing list of items. + _itemList?.Clear(); + + // Add any existing items to our list. + if (value is not null) + { + if (Context is not null) + { + // Create a new list around the new value. + _itemList = new(this, _listBoxItems.Items, value); + + ToolStrip realToolStrip = ToolStripFromObject(Context.Instance); + _itemList.Add(realToolStrip); + + if (Context.Instance is ToolStripItem itemInstance && itemInstance.Site is not null) + { + Text = $"{_originalText} ({itemInstance.Site.Name}.{Context.PropertyDescriptor.Name})"; + } + + foreach (ToolStripItem item in value) + { + if (item is DesignerToolStripControlHost) + { + continue; + } + + _itemList.Add(item); + } + + if (Context.GetService() is IComponentChangeService changeService) + { + changeService.ComponentChanged += OnComponentChanged; + } + + _selectedItemProps.Site = new PropertyGridSite(Context, _selectedItemProps); + } + } + else + { + if (_componentChangeSvc is not null) + { + _componentChangeSvc.ComponentChanged -= OnComponentChanged; + } + + _componentChangeSvc = null; + _selectedItemProps.Site = null; + } + + _targetToolStripCollection = value; + } + } + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + ComponentResourceManager resources = new(typeof(ToolStripItemEditorForm)); + _btnCancel = new(); + _btnOK = new(); + _tableLayoutPanel = new(); + _addTableLayoutPanel = new(); + _btnAddNew = new(); + _newItemTypes = new(); + _okCancelTableLayoutPanel = new(); + _lblItems = new(); + _selectedItemName = new(); + _selectedItemProps = new(); + _lblMembers = new(); + _listBoxItems = new(); + _btnMoveUp = new(); + _btnMoveDown = new(); + _btnRemove = new(); + _tableLayoutPanel.SuspendLayout(); + _addTableLayoutPanel.SuspendLayout(); + _okCancelTableLayoutPanel.SuspendLayout(); + SuspendLayout(); + // btnCancel + resources.ApplyResources(_btnCancel, "btnCancel"); + _btnCancel.DialogResult = DialogResult.Cancel; + _btnCancel.Margin = new(3, 0, 0, 0); + _btnCancel.Name = "btnCancel"; + // btnOK + resources.ApplyResources(_btnOK, "btnOK"); + _btnOK.Margin = new(0, 0, 3, 0); + _btnOK.Name = "btnOK"; + // tableLayoutPanel + resources.ApplyResources(_tableLayoutPanel, "tableLayoutPanel"); + _tableLayoutPanel.ColumnStyles.Add(new(SizeType.Absolute, 274F)); + _tableLayoutPanel.ColumnStyles.Add(new()); + _tableLayoutPanel.ColumnStyles.Add(new(SizeType.Percent, 100F)); + _tableLayoutPanel.Controls.Add(_addTableLayoutPanel, 0, 1); + _tableLayoutPanel.Controls.Add(_okCancelTableLayoutPanel, 0, 6); + _tableLayoutPanel.Controls.Add(_lblItems, 0, 0); + _tableLayoutPanel.Controls.Add(_selectedItemName, 2, 0); + _tableLayoutPanel.Controls.Add(_selectedItemProps, 2, 1); + _tableLayoutPanel.Controls.Add(_lblMembers, 0, 2); + _tableLayoutPanel.Controls.Add(_listBoxItems, 0, 3); + _tableLayoutPanel.Controls.Add(_btnMoveUp, 1, 3); + _tableLayoutPanel.Controls.Add(_btnMoveDown, 1, 4); + _tableLayoutPanel.Controls.Add(_btnRemove, 1, 5); + _tableLayoutPanel.Name = "tableLayoutPanel"; + _tableLayoutPanel.RowStyles.Add(new()); + _tableLayoutPanel.RowStyles.Add(new()); + _tableLayoutPanel.RowStyles.Add(new()); + _tableLayoutPanel.RowStyles.Add(new()); + _tableLayoutPanel.RowStyles.Add(new()); + _tableLayoutPanel.RowStyles.Add(new(SizeType.Percent, 100F)); + _tableLayoutPanel.RowStyles.Add(new()); + // addTableLayoutPanel + resources.ApplyResources(_addTableLayoutPanel, "addTableLayoutPanel"); + _addTableLayoutPanel.ColumnStyles.Add(new(SizeType.Percent, 100F)); + _addTableLayoutPanel.ColumnStyles.Add(new()); + _addTableLayoutPanel.Controls.Add(_btnAddNew, 1, 0); + _addTableLayoutPanel.Controls.Add(_newItemTypes, 0, 0); + _addTableLayoutPanel.Margin = new(0, 3, 3, 3); + _addTableLayoutPanel.Name = "addTableLayoutPanel"; + _addTableLayoutPanel.AutoSize = true; + _addTableLayoutPanel.RowStyles.Add(new()); + // btnAddNew + resources.ApplyResources(_btnAddNew, "btnAddNew"); + _btnAddNew.Margin = new(3, 0, 0, 0); + _btnAddNew.Name = "btnAddNew"; + // newItemTypes + resources.ApplyResources(_newItemTypes, "newItemTypes"); + _newItemTypes.DropDownStyle = ComboBoxStyle.DropDownList; + _newItemTypes.FormattingEnabled = true; + _newItemTypes.Margin = new(0, 0, 3, 0); + _newItemTypes.Name = "newItemTypes"; + _newItemTypes.DrawMode = DrawMode.OwnerDrawVariable; + + // okCancelTableLayoutPanel + resources.ApplyResources(_okCancelTableLayoutPanel, "okCancelTableLayoutPanel"); + _tableLayoutPanel.SetColumnSpan(_okCancelTableLayoutPanel, 3); + _okCancelTableLayoutPanel.ColumnStyles.Add(new(SizeType.Percent, 50F)); + _okCancelTableLayoutPanel.ColumnStyles.Add(new(SizeType.Percent, 50F)); + _okCancelTableLayoutPanel.Controls.Add(_btnOK, 0, 0); + _okCancelTableLayoutPanel.Controls.Add(_btnCancel, 1, 0); + _okCancelTableLayoutPanel.Margin = new(3, 6, 0, 0); + _okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel"; + _okCancelTableLayoutPanel.RowStyles.Add(new()); + // lblItems + resources.ApplyResources(_lblItems, "lblItems"); + _lblItems.Margin = new(0, 3, 3, 0); + _lblItems.Name = "lblItems"; + // selectedItemName + resources.ApplyResources(_selectedItemName, "selectedItemName"); + _selectedItemName.Margin = new(3, 3, 3, 0); + _selectedItemName.Name = "selectedItemName"; + // selectedItemProps + _selectedItemProps.CommandsVisibleIfAvailable = false; + resources.ApplyResources(_selectedItemProps, "selectedItemProps"); + _selectedItemProps.Margin = new(3, 3, 0, 3); + _selectedItemProps.Name = "selectedItemProps"; + _tableLayoutPanel.SetRowSpan(_selectedItemProps, 5); + // lblMembers + resources.ApplyResources(_lblMembers, "lblMembers"); + _lblMembers.Margin = new(0, 3, 3, 0); + _lblMembers.Name = "lblMembers"; + // listBoxItems + resources.ApplyResources(_listBoxItems, "listBoxItems"); + _listBoxItems.DrawMode = DrawMode.OwnerDrawVariable; + _listBoxItems.FormattingEnabled = true; + _listBoxItems.Margin = new(0, 3, 3, 3); + _listBoxItems.Name = "listBoxItems"; + _tableLayoutPanel.SetRowSpan(_listBoxItems, 3); + _listBoxItems.SelectionMode = SelectionMode.MultiExtended; + // btnMoveUp + resources.ApplyResources(_btnMoveUp, "btnMoveUp"); + _btnMoveUp.Margin = new(3, 3, 18, 0); + _btnMoveUp.Name = "btnMoveUp"; + // btnMoveDown + resources.ApplyResources(_btnMoveDown, "btnMoveDown"); + _btnMoveDown.Margin = new(3, 1, 18, 3); + _btnMoveDown.Name = "btnMoveDown"; + // btnRemove + resources.ApplyResources(_btnRemove, "btnRemove"); + _btnRemove.Margin = new(3, 3, 18, 3); + _btnRemove.Name = "btnRemove"; + // ToolStripCollectionEditor + AutoScaleMode = AutoScaleMode.Font; + AcceptButton = _btnOK; + resources.ApplyResources(this, "$this"); + CancelButton = _btnCancel; + Controls.Add(_tableLayoutPanel); + HelpButton = true; + MaximizeBox = false; + MinimizeBox = false; + Name = "ToolStripCollectionEditor"; + Padding = new(9); + ShowIcon = false; + ShowInTaskbar = false; + SizeGripStyle = SizeGripStyle.Show; + _tableLayoutPanel.ResumeLayout(false); + _tableLayoutPanel.PerformLayout(); + _addTableLayoutPanel.ResumeLayout(false); + _addTableLayoutPanel.PerformLayout(); + _okCancelTableLayoutPanel.ResumeLayout(false); + _okCancelTableLayoutPanel.PerformLayout(); + ResumeLayout(false); + + // Events + HelpButtonClicked += ToolStripCollectionEditor_HelpButtonClicked; + _newItemTypes.DropDown += OnNewItemTypes_DropDown; + _newItemTypes.HandleCreated += OnComboHandleCreated; + _newItemTypes.SelectedIndexChanged += OnNewItemTypes_SelectedIndexChanged; + _btnAddNew.Click += OnNewItemTypes_SelectionChangeCommitted; + _btnMoveUp.Click += OnBtnMoveUp_Click; + _btnMoveDown.Click += OnBtnMoveDown_Click; + _btnRemove.Click += OnBtnRemove_Click; + _btnOK.Click += OnBtnOK_Click; + _selectedItemName.Paint += OnSelectedItemName_Paint; + _listBoxItems.SelectedIndexChanged += OnListBoxItems_SelectedIndexChanged; + _listBoxItems.DrawItem += OnListBoxItems_DrawItem; + _listBoxItems.MeasureItem += OnListBoxItems_MeasureItem; + + _selectedItemProps.PropertyValueChanged += PropertyGrid_propertyValueChanged; + Load += OnFormLoad; + } + #endregion + + /// + /// Create a new button bitmap scaled for the device units. + /// Note: original image might be disposed. + /// + /// button with an image, image size is defined in logical units + private static void ScaleButtonImageLogicalToDevice(Button button) + { + if (button?.Image is not Bitmap buttonBitmap) + { + return; + } + + button.Image = ScaleHelper.ScaleToDpi(buttonBitmap, ScaleHelper.InitialSystemDpi, disposeBitmap: true); + } + + private void OnComboHandleCreated(object sender, EventArgs e) + { + // BUGBUG: syncing the MeasureItem event forces handle creation. + _newItemTypes.HandleCreated -= OnComboHandleCreated; + + _newItemTypes.MeasureItem += OnListBoxItems_MeasureItem; + _newItemTypes.DrawItem += OnListBoxItems_DrawItem; + } + + /// + /// Add a new item to our list. This will add a preview item + /// and a list box item as well. + /// + /// The item we're adding + /// The index to add it at, or -1 to add it at the end. + private void AddItem(ToolStripItem newItem, int index) + { + if (index == -1) + { + _itemList.Add(newItem); + } + else + { + // Make sure we're legit. + if (index < 0 || index >= _itemList.Count) + { + return; + } + + _itemList.Insert(index, newItem); + } + + ToolStrip ownerToolStrip = Context is { Instance: not null } contextInstance + ? ToolStripFromObject(contextInstance) + : null; + + // Set the owner to be the real ToolStrip + ownerToolStrip?.Items.Add(newItem); + + // Clear the current selection and set a new one. + _listBoxItems.ClearSelected(); + _listBoxItems.SelectedItem = newItem; + } + + /// + /// Move an item from one index to the other. + /// + private void MoveItem(int fromIndex, int toIndex) + { + _itemList.Move(fromIndex, toIndex); + } + + private void OnComponentChanged(object sender, ComponentChangedEventArgs e) + { + if (e.Component is ToolStripItem && e.Member is PropertyDescriptor && e.Member.Name == "Name") + { + _lblItems.Invalidate(); + } + } + + /// + /// Pick up the new collection value. + /// + protected override void OnEditValueChanged() + { + _selectedItemProps.SelectedObjects = null; + Collection = (ToolStripItemCollection)EditValue; + } + + /// + /// Called when the form loads...add the types from the list into the combo box. + /// + /// + /// + private void OnFormLoad(object sender, EventArgs e) + { + // Set the font as appropriate. + _newItemTypes.ItemHeight = Math.Max(s_iconHeight, Font.Height); + + if (Context.Instance is not Component component) + { + return; + } + + Type[] newToolStripItemTypes = ToolStripDesignerUtils.GetStandardItemTypes(component); + + _newItemTypes.Items.Clear(); + foreach (Type t in newToolStripItemTypes) + { + _newItemTypes.Items.Add(new TypeListItem(t)); + } + + _newItemTypes.SelectedIndex = 0; + + _customItemIndex = -1; + + newToolStripItemTypes = ToolStripDesignerUtils.GetCustomItemTypes(component, component.Site); + if (newToolStripItemTypes.Length > 0) + { + _customItemIndex = _newItemTypes.Items.Count; + foreach (Type t in newToolStripItemTypes) + { + _newItemTypes.Items.Add(new TypeListItem(t)); + } + } + + if (_listBoxItems.Items.Count > 0) + { + _listBoxItems.SelectedIndex = 0; + } + } + + /// + /// Handle a click of the OK button. + /// + /// + /// + private void OnBtnOK_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + } + + private void ToolStripCollectionEditor_HelpButtonClicked(object sender, CancelEventArgs e) + { + e.Cancel = true; + _editor.ShowHelp(); + } + + /// + /// Remove all the selected items. + /// + private void OnBtnRemove_Click(object sender, EventArgs e) + { + // Move the selected items into an array so it doesn't change as we remove from it. + ToolStripItem[] items = new ToolStripItem[_listBoxItems.SelectedItems.Count]; + _listBoxItems.SelectedItems.CopyTo(items, 0); + + // Now remove each of the items. + for (int i = 0; i < items.Length; i++) + { + RemoveItem(items[i]); + } + } + + /// + /// Move the selected item down one notch in the list. + /// + /// + /// + private void OnBtnMoveDown_Click(object sender, EventArgs e) + { + ToolStripItem currentItem = (ToolStripItem)_listBoxItems.SelectedItem; + int currentIndex = _listBoxItems.Items.IndexOf(currentItem); + MoveItem(currentIndex, ++currentIndex); + _listBoxItems.SelectedIndex = currentIndex; + } + + /// + /// Move the selected item up one notch in the list. + /// + private void OnBtnMoveUp_Click(object sender, EventArgs e) + { + ToolStripItem currentItem = (ToolStripItem)_listBoxItems.SelectedItem; + int currentIndex = _listBoxItems.Items.IndexOf(currentItem); + if (currentIndex > 1) + { + MoveItem(currentIndex, --currentIndex); + _listBoxItems.SelectedIndex = currentIndex; + } + } + + /// + /// When we drop the combo, make sure it's wide enough to show the + /// full text from all the items. + /// + private void OnNewItemTypes_DropDown(object sender, EventArgs e) + { + if (_newItemTypes.Tag is null || !(bool)_newItemTypes.Tag) + { + int itemWidth = _newItemTypes.ItemHeight; + int dropDownHeight = 0; + + // Walk the items and get the widest one. + using (Graphics g = _newItemTypes.CreateGraphics()) + { + foreach (TypeListItem item in _newItemTypes.Items) + { + itemWidth = (int)Math.Max(itemWidth, _newItemTypes.ItemHeight + 1 + + g.MeasureString(item.Type.Name, _newItemTypes.Font).Width + GdiPlusExtraSpace); + dropDownHeight += (Font.Height + s_separatorHeight) + 2 * s_imagePaddingY; + } + } + + _newItemTypes.DropDownWidth = itemWidth; + _newItemTypes.DropDownHeight = dropDownHeight; + + // Store that we've already done this work. + _newItemTypes.Tag = true; + } + } + + /// + /// When the user makes an actual selection change, add an item to the ToolStrip. + /// + /// + /// + // Okay to not catch non-CLS compliant exceptions + private void OnNewItemTypes_SelectionChangeCommitted(object sender, EventArgs e) + { + // Get the item type. + if (_newItemTypes.SelectedItem is not TypeListItem typeItem) + { + return; + } + + // Create the ToolStripItem. + ToolStripItem newItem = (ToolStripItem)CreateInstance(typeItem.Type); + // Set the Image property and DisplayStyle. + if (newItem is ToolStripButton or ToolStripSplitButton or ToolStripDropDownButton) + { + Image image = null; + try + { + image = new Bitmap(typeof(ToolStripItemEditorForm), "BlankToolstrip.bmp"); + } + catch (Exception ex) + { + if (ex.IsCriticalException()) + { + throw; + } + } + + PropertyDescriptor imageProperty = TypeDescriptor.GetProperties(newItem)[nameof(Image)]; + + if (imageProperty is not null && image is not null) + { + imageProperty.SetValue(newItem, image); + } + + PropertyDescriptor displayProperty = TypeDescriptor.GetProperties(newItem)["DisplayStyle"]; + displayProperty?.SetValue(newItem, ToolStripItemDisplayStyle.Image); + + PropertyDescriptor imageTransProperty = TypeDescriptor.GetProperties(newItem)["ImageTransparentColor"]; + imageTransProperty?.SetValue(newItem, Color.Magenta); + } + + // Add it. + AddItem(newItem, -1); + _listBoxItems.Focus(); + } + + /// + /// Just invalidate the combo on a selection change. + /// + private void OnNewItemTypes_SelectedIndexChanged(object sender, EventArgs e) + { + _newItemTypes.Invalidate(); + } + + /// + /// Custom measureItem for the ListBox items... + /// + private void OnListBoxItems_MeasureItem(object sender, MeasureItemEventArgs e) + { + int separator = 0; + if (sender is ComboBox) + { + bool drawSeparator = e.Index == _customItemIndex; + + if (e.Index >= 0 && drawSeparator) + { + separator = s_separatorHeight; + } + } + + Font measureFont = Font; + e.ItemHeight = Math.Max(s_iconHeight + separator, measureFont.Height + separator) + 2 * s_imagePaddingY; + } + + /// + /// Custom draw the list box item with the icon and the text. + /// We actually share this code between the list box and the combo box. + /// + private void OnListBoxItems_DrawItem(object sender, DrawItemEventArgs e) + { + if (e.Index == -1) + { + return; + } + + // Fish out the item type. we're so cool we can share this code + // with just this difference. + Type itemType; + string itemText; + bool indentItem = false; + bool drawSeparator = false; + bool isComboEditBox = (e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit; + + if (sender is ListBox listBox) + { + // The list box has the items directly. + if (listBox.Items[e.Index] is not Component item) + { + Debug.Fail("Unexpected list box item painted!"); + return; + } + + if (item is ToolStripItem) + { + indentItem = true; + } + + itemType = item.GetType(); + itemText = (item.Site is not null) ? item.Site.Name : itemType.Name; + } + else if (sender is ComboBox box) + { + // The combo box has just the types. + // Never draw the separator in the edit box, even if it is the selected index. + drawSeparator = (e.Index == _customItemIndex) && !isComboEditBox; + if (box.Items[e.Index] is not TypeListItem typeListItem) + { + Debug.Fail("Unexpected combo box item!"); + return; + } + + itemType = typeListItem.Type; + itemText = typeListItem.ToString(); + } + else + { + Debug.Fail("Unexpected sender calling DrawItem"); + return; + } + + // We've got ourselves an item type. draw it. + if (itemType is not null) + { + if (drawSeparator) + { + e.Graphics.DrawLine(SystemPens.ControlDark, e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Right - 2, e.Bounds.Y + 2); + } + + // Get the toolbox bitmap, draw it, and then draw the text. We just + // draw the bitmap as a square based on the height of this line item. + // Calculate the image rect + Rectangle imageBounds = e.Bounds; + imageBounds.Size = new(s_iconWidth, s_iconHeight); + int xOffset = isComboEditBox ? 0 : s_imagePaddingX * 2; + imageBounds.Offset(xOffset, s_imagePaddingX); + + if (drawSeparator) + { + imageBounds.Offset(0, s_separatorHeight); + } + + if (indentItem) + { + imageBounds.X += s_iconWidth + s_indentSpacing; + } + + // Make sure after all this we still are within bounds and are square. + if (!isComboEditBox) + { + imageBounds.Intersect(e.Bounds); + } + + // Draw the image if it's there. + Bitmap tbxBitmap = ToolStripDesignerUtils.GetToolboxBitmap(itemType); + if (tbxBitmap is not null) + { + if (isComboEditBox) + { + // Paint the icon of the combo's textbox area. + e.Graphics.DrawImage(tbxBitmap, e.Bounds.X, e.Bounds.Y, s_iconWidth, s_iconHeight); + } + else + { + e.Graphics.FillRectangle(SystemBrushes.Window, imageBounds); + e.Graphics.DrawImage(tbxBitmap, imageBounds); + } + } + + // Calculate the text rect + Rectangle textBounds = e.Bounds; + textBounds.X = imageBounds.Right + s_textImageSpacing; + textBounds.Y = imageBounds.Top - s_imagePaddingY; + if (!isComboEditBox) + { + textBounds.Y += s_imagePaddingY * 2; + } + + textBounds.Intersect(e.Bounds); + + // Draw the background as necessary. + Rectangle fillBounds = e.Bounds; + fillBounds.X = textBounds.X - 2; + + if (drawSeparator) + { + fillBounds.Y += s_separatorHeight; + fillBounds.Height -= s_separatorHeight; + } + + Color textColor; + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) + { + textColor = SystemColors.HighlightText; + e.Graphics.FillRectangle(SystemBrushes.Highlight, fillBounds); + } + else + { + textColor = SystemColors.WindowText; + e.Graphics.FillRectangle(SystemBrushes.Window, fillBounds); + } + + // Render the text. + if (!string.IsNullOrEmpty(itemText)) + { + TextFormatFlags format = TextFormatFlags.Top | TextFormatFlags.Left; + TextRenderer.DrawText(e.Graphics, itemText, Font, textBounds, textColor, format); + } + + // Finally, draw the focus rect. + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) + { + fillBounds.Width -= 1; + ControlPaint.DrawFocusRectangle(e.Graphics, fillBounds, e.ForeColor, e.BackColor); + } + } + } + + /// + /// Push the selected items into the property grid. + /// + /// + /// + private void OnListBoxItems_SelectedIndexChanged(object sender, EventArgs e) + { + // Push the items into the grid. + object[] selectedItems = [_listBoxItems.SelectedItems.Count]; + if (selectedItems.Length > 0) + { + _listBoxItems.SelectedItems.CopyTo(selectedItems, 0); + } + + // ToolStrip is selected. Remove the items property. + if (selectedItems.Length == 1 && selectedItems[0] is ToolStrip toolStrip) + { + ToolStrip parentStrip = toolStrip; + if (parentStrip is not null && parentStrip.Site is not null) + { + _toolStripCustomTypeDescriptor ??= new(toolStrip); + + _selectedItemProps.SelectedObjects = [_toolStripCustomTypeDescriptor]; + } + else + { + // If null parentStrip or non sited then don't show the properties. + _selectedItemProps.SelectedObjects = null; + } + } + else + { + _selectedItemProps.SelectedObjects = selectedItems; + } + + // Enable the up/down button and the remove button based on the items. + _btnMoveUp.Enabled = (_listBoxItems.SelectedItems.Count == 1) && (_listBoxItems.SelectedIndex > 1); + _btnMoveDown.Enabled = (_listBoxItems.SelectedItems.Count == 1) && (_listBoxItems.SelectedIndex < _listBoxItems.Items.Count - 1); + _btnRemove.Enabled = selectedItems.Length > 0; + + // Cannot remove a ToolStrip through this CollectionEditor. + foreach (object obj in _listBoxItems.SelectedItems) + { + if (obj is ToolStrip) + { + _btnRemove.Enabled = _btnMoveUp.Enabled = _btnMoveDown.Enabled = false; + break; + } + } + + // Invalidate the list box and the label above the grid. + _listBoxItems.Invalidate(); + _selectedItemName.Invalidate(); + } + + /// + /// Invalidate the and the SelectedItemName Label on top of the propertyGrid. + /// + private void PropertyGrid_propertyValueChanged(object sender, PropertyValueChangedEventArgs e) + { + // Invalidate the list box and the label above the grid. + _listBoxItems.Invalidate(); + _selectedItemName.Invalidate(); + } + + /// + /// Paint the name and type of the currently selected items in the label above the property grid. + /// + private void OnSelectedItemName_Paint(object sender, PaintEventArgs e) + { + // Make the bolded font for the type name. + using Font boldFont = new(_selectedItemName.Font, FontStyle.Bold); + Label label = sender as Label; + Rectangle bounds = label.ClientRectangle; + StringFormat stringFormat = null; + + bool rightToLeft = label.RightToLeft == RightToLeft.Yes; + + stringFormat = rightToLeft ? new(StringFormatFlags.DirectionRightToLeft) : new(); + + stringFormat.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show; + + // Based on the count, just paint the name, (Multiple Items), or (None). + switch (_listBoxItems.SelectedItems.Count) + { + case 1: + // For a single item, we paint it's class name in bold, then the item name. + Component selectedItem = null; + selectedItem = _listBoxItems.SelectedItem is ToolStrip strip ? strip : (ToolStripItem)_listBoxItems.SelectedItem; + + string className = "&" + selectedItem.GetType().Name; + if (selectedItem.Site is not null) + { + // Erase background + e.Graphics.FillRectangle(SystemBrushes.Control, bounds); + string itemName = selectedItem.Site.Name; + + if (label is not null) + { + label.Text = className + itemName; + } + + int classWidth = 0; + classWidth = (int)e.Graphics.MeasureString(className, boldFont).Width; + e.Graphics.DrawString(className, boldFont, SystemBrushes.WindowText, bounds, stringFormat); + int itemTextWidth = (int)e.Graphics.MeasureString(itemName, _selectedItemName.Font).Width; + Rectangle textRect = new(classWidth + GdiPlusExtraSpace, 0, bounds.Width - (classWidth + GdiPlusExtraSpace), bounds.Height); + label.AutoEllipsis = itemTextWidth > textRect.Width; + + TextFormatFlags flags = TextFormatFlags.EndEllipsis | TextFormatFlags.PreserveGraphicsTranslateTransform | TextFormatFlags.PreserveGraphicsClipping; + if (rightToLeft) + { + flags |= TextFormatFlags.RightToLeft; + } + + TextRenderer.DrawText(e.Graphics, itemName, _selectedItemName.Font, textRect, SystemColors.WindowText, flags); + } + + break; + case 0: + // Erase background. + e.Graphics.FillRectangle(SystemBrushes.Control, bounds); + if (label is not null) + { + label.Text = SR.ToolStripItemCollectionEditorLabelNone; + } + + e.Graphics.DrawString(SR.ToolStripItemCollectionEditorLabelNone, boldFont, SystemBrushes.WindowText, bounds, stringFormat); + break; + default: + // Erase background. + e.Graphics.FillRectangle(SystemBrushes.Control, bounds); + if (label is not null) + { + label.Text = SR.ToolStripItemCollectionEditorLabelMultipleItems; + } + + e.Graphics.DrawString(SR.ToolStripItemCollectionEditorLabelMultipleItems, boldFont, SystemBrushes.WindowText, bounds, stringFormat); + break; + } + + stringFormat.Dispose(); + } + + /// + /// Removes an item from the list and the preview ToolStrip + /// + /// + private void RemoveItem(ToolStripItem item) + { + int index; + try + { + // Remove the item from the list. + index = _itemList.IndexOf(item); + _itemList.Remove(item); + } + finally + { + item.Dispose(); + } + + // Now set up our selection. + if (_itemList.Count > 0) + { + _listBoxItems.ClearSelected(); + index = Math.Max(0, Math.Min(index, _listBoxItems.Items.Count - 1)); + _listBoxItems.SelectedIndex = index; + } + } + + /// + /// Fishes out the ToolStrip from the object - which can be a ToolStrip or a + /// + internal static ToolStrip ToolStripFromObject(object instance) + { + ToolStrip currentToolStrip = null; + + if (instance is not null) + { + currentToolStrip = instance is ToolStripDropDownItem toolStripDropDownItem ? toolStripDropDownItem.DropDown : instance as ToolStrip; + } + + return currentToolStrip; + } + + private class ImageComboBox : ComboBox + { + public ImageComboBox() + { + } + + private Rectangle ImageRect + { + get + { + // Need to add padding for RTL combo box. + return RightToLeft == RightToLeft.Yes + ? new(4 + SystemInformation.HorizontalScrollBarThumbWidth, 3, s_iconWidth, s_iconHeight) + : new(3, 3, s_iconWidth, s_iconHeight); + } + } + + protected override void OnDropDownClosed(EventArgs e) + { + base.OnDropDownClosed(e); + Invalidate(ImageRect); + } + + protected override void OnSelectedIndexChanged(EventArgs e) + { + base.OnSelectedIndexChanged(e); + Invalidate(ImageRect); + } + + protected override void WndProc(ref Message m) + { + base.WndProc(ref m); + switch (m.MsgInternal) + { + case PInvokeCore.WM_SETFOCUS: + case PInvokeCore.WM_KILLFOCUS: + Invalidate(ImageRect); + break; + } + } + } + + /// + /// This is a magic collection. It's job is to keep the preview ToolStrip and the list box in sync and manage both sets of items. + /// It contains a list of EditorItem objects, which whole the information for each item, and a reference to the real ToolStripItem component, + /// the and the preview ToolStripItem. The order and contents of this combo box always match that of the real collection, the list box, and the preview ToolStrip. + /// It operates generically on three ILists: the list box.Items collection, the previewToolStrip.Items collection, and the actual ToolStripItemCollection being designed. + /// + private class EditorItemCollection : CollectionBase + { + // The ListBox.Items collection. + private readonly IList _listBoxList; + // The real deal target collection. + private readonly IList _targetCollectionList; + // The owner form that created this collection. + private readonly ToolStripItemEditorForm _owner; + + /// + /// Setup the collection's variables. + /// + internal EditorItemCollection(ToolStripItemEditorForm owner, IList displayList, IList componentList) + { + _owner = owner; + _listBoxList = displayList; + _targetCollectionList = componentList; + } + + /// + /// Add a new ToolStrip item. See OnInsertComplete for the actual add operation. + /// + /// + public void Add(object item) + { + List.Add(new EditorItem(item)); + } + + /// + /// This is a little tricky, since our list doesn't actually contain + /// ToolStripItems, but rather EditorItems, we have to walk those. No bother, + /// this list is always pretty short. + /// + public int IndexOf(ToolStripItem item) + { + for (int i = 0; i < List.Count; i++) + { + EditorItem editorItem = (EditorItem)List[i]!; + if (editorItem.Component == item) + { + return i; + } + } + + return -1; + } + + /// + /// Insert an item into the list somewhere. See OnInsertComplete for the real meaty stuff. + /// + /// + /// + public void Insert(int index, ToolStripItem item) + { + List.Insert(index, new EditorItem(item)); + } + + /// + /// Move an item from one array position to another. + /// + public void Move(int fromIndex, int toIndex) + { + if (toIndex == fromIndex) + { + return; + } + + EditorItem editorItem = (EditorItem)List[fromIndex]!; + if (editorItem.Host is not null) + { + return; + } + + try + { + _owner.Context?.OnComponentChanging(); + + // Yank 'em all outate there. + _listBoxList.Remove(editorItem.Component); + _targetCollectionList.Remove(editorItem.Component); + + InnerList.Remove(editorItem); + + // Put 'em all back in. + _listBoxList.Insert(toIndex, editorItem.Component); + // Since ToolStrip is also an item of the listBoxItems + // Lets decrement the counter by one. + + // ToolStrip is Always the TOP item + // so it is SAFE to assume that + // the index that we want is always currentIndex - 1. + + // This is required as the _targetList doesn't contain the ToolStrip. + _targetCollectionList.Insert(toIndex - 1, editorItem.Component); + + InnerList.Insert(toIndex, editorItem); + } + finally + { + _owner.Context?.OnComponentChanged(); + } + } + + /// + /// Clear has a different semantic than remove. Clear simply dumps all the items + /// out of the list box and the preview and zero's this collection. Remove is more + /// destructive in that it affects the target collection. + /// + protected override void OnClear() + { + _listBoxList.Clear(); + foreach (EditorItem item in List) + { + item.Dispose(); + } + + // We don't do sync target list here. + base.OnClear(); + } + + /// + /// After an item is inserted into the collection, we do the work + /// to make sure that we sync up the three lists. + /// + /// + /// + protected override void OnInsertComplete(int index, object value) + { + if (value is null) + { + return; + } + + EditorItem item = (EditorItem)value; + if (item.Host is not null) + { + // Insert into the list box. + _listBoxList.Insert(index, item.Host); + base.OnInsertComplete(index, value); + return; + } + + // Check the target collection first, if it's already there, + // chill. Otherwise we need to push it in. In the case that we're + // sync'ing to an existing list, we don't want to be re-adding everything. + if (!_targetCollectionList.Contains(item.Component)) + { + try + { + _owner.Context?.OnComponentChanging(); + _targetCollectionList.Insert(index - 1, item.Component); + } + finally + { + _owner.Context?.OnComponentChanged(); + } + } + + // Insert into the list box and into the preview + _listBoxList.Insert(index, item.Component); + base.OnInsertComplete(index, value); + } + + /// + /// Really remove an item from the collections. + /// + protected override void OnRemove(int index, object value) + { + object item = List[index]; + if (item is null) + { + return; + } + + EditorItem editorItem = (EditorItem)item!; + + // Pull it from the list box and preview + _listBoxList.RemoveAt(index); + + // Yank it from the collection. The code that calls this + // collection is responsible for disposing it to destroy + // it in the designer. + try + { + _owner.Context?.OnComponentChanging(); + _targetCollectionList.RemoveAt(index - 1); + } + finally + { + _owner.Context?.OnComponentChanged(); + } + + // Finally dispose the editor item which cleanup the preview item. + editorItem?.Dispose(); + base.OnRemove(index, value); + } + + /// + /// Remove an item.See OnRemove for details. + /// + /// + public void Remove(ToolStripItem item) + { + int index = IndexOf(item); + List.RemoveAt(index); + } + + /// + /// This class keeps track of the mapping between a ToolStrip item in the designer, in the + /// preview ToolStrip, and in the list box. + /// + private class EditorItem + { + // The real deal item in the designer. + public ToolStripItem _component; + public ToolStrip _host; + + internal EditorItem(object componentItem) + { + if (componentItem is ToolStrip toolStrip) + { + _host = toolStrip; + } + else + { + _component = (ToolStripItem)componentItem; + } + } + + /// + /// The item that's actually being created in the designer. + /// + public ToolStripItem Component => _component; + + /// + /// The ToolStrip that's actually being created in the designer. + /// + public ToolStrip Host => _host; + + /// + /// Cleanup our mess. + /// + public void Dispose() + { + GC.SuppressFinalize(this); + _component = null; + } + } + } + + private class TypeListItem + { + public readonly Type Type; + + public TypeListItem(Type type) + { + Type = type; + } + + public override string ToString() + { + return ToolStripDesignerUtils.GetToolboxDescription(Type); + } + } + } +} diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCollectionEditor.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCollectionEditor.cs new file mode 100644 index 00000000000..3b20702de56 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCollectionEditor.cs @@ -0,0 +1,85 @@ +// 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; + +namespace System.Windows.Forms.Design +{ + internal partial class ToolStripCollectionEditor : CollectionEditor + { + public ToolStripCollectionEditor() : base(typeof(ToolStripItemCollection)) + { + } + + /// + /// Overridden to reaction our editor form instead of the standard collection editor form. + /// + /// An instance of a ToolStripItemEditorForm + protected override CollectionForm CreateCollectionForm() => new ToolStripItemEditorForm(this); + + /// + /// Gets the help topic to display for the dialog help button or pressing F1. Override to + /// display a different help topic. + /// + protected override string HelpTopic => "net.ComponentModel.ToolStripCollectionEditor"; + + /// + /// Check the owner. + /// + public override object? EditValue(ITypeDescriptorContext? context, IServiceProvider provider, object? value) + { + if (provider is null) + { + return null; + } + + // get ahold of the designer for the component that is launching this editor. + // If it is a win bar, then we want to let it know this editor is up. + ToolStripDesigner? designer = null; + + // see if the selected component is a windows bar or windows bar toolStripDropDownItem that is directly on the form. + ISelectionService? selectionService = provider.GetService(); + if (selectionService is not null) + { + object? primarySelection = selectionService.PrimarySelection; + + // if it's a drop down toolStripDropDownItem, just pop up to it's owner. + if (primarySelection is ToolStripDropDownItem toolStripDropDownItem) + { + primarySelection = toolStripDropDownItem.Owner; + } + + // Now get the designer. + if (primarySelection is ToolStrip) + { + IDesignerHost? host = provider.GetService(); + if (host is not null) + { + designer = host.GetDesigner((IComponent)primarySelection) as ToolStripDesigner; + } + } + } + + try + { + if (designer is not null) + { + designer.EditingCollection = true; + } + + using (ScaleHelper.EnterDpiAwarenessScope(DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)) + { + return base.EditValue(context, provider, value); + } + } + finally + { + if (designer is not null) + { + designer.EditingCollection = false; + } + } + } + } +} diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCustomTypeDescriptor.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCustomTypeDescriptor.cs new file mode 100644 index 00000000000..6fb5583222a --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripCustomTypeDescriptor.cs @@ -0,0 +1,95 @@ +// 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; + +namespace System.Windows.Forms.Design; + +internal class ToolStripCustomTypeDescriptor : CustomTypeDescriptor +{ + private readonly ToolStrip _instance; + private PropertyDescriptor? _propItems; + private PropertyDescriptorCollection? _collection; + + public ToolStripCustomTypeDescriptor(ToolStrip instance) : base() + { + _instance = instance; + } + + /// + /// The GetPropertyOwner method returns an instance of an object that + /// owns the given property for the object this type descriptor is representing. + /// An optional attribute array may be provided to filter the collection that is + /// returned. Returning null from this method causes the TypeDescriptor object + /// to use its default type description services. + /// + /// PropertyDescriptor + /// + public override object GetPropertyOwner(PropertyDescriptor? pd) => _instance; + + /// + /// The GetProperties method returns a collection of property descriptors + /// for the object this type descriptor is representing. An optional + /// attribute array may be provided to filter the collection that is returned + /// If no parent is provided,this will return an empty + /// property collection. + /// + /// + public override PropertyDescriptorCollection GetProperties() + { + if (_instance is not null && _collection is null) + { + PropertyDescriptorCollection retColl = TypeDescriptor.GetProperties(_instance); + PropertyDescriptor[] propArray = new PropertyDescriptor[retColl.Count]; + + retColl.CopyTo(propArray, 0); + + _collection = new PropertyDescriptorCollection(propArray, false); + } + + if (_collection?.Count > 0) + { + _propItems = _collection["Items"]; + if (_propItems is not null) + { + _collection.Remove(_propItems); + } + } + + return _collection!; + } + + /// + /// The GetProperties method returns a collection of property descriptors + /// for the object this type descriptor is representing. An optional + /// attribute array may be provided to filter the collection that is returned. + /// If no parent is provided,this will return an empty + /// property collection. + /// Here we will pass the "collection without the "items" property. + /// + /// + /// + public override PropertyDescriptorCollection GetProperties(Attribute[]? attributes) + { + if (_instance is not null && _collection is null) + { + PropertyDescriptorCollection retColl = TypeDescriptor.GetProperties(_instance); + PropertyDescriptor[] propArray = new PropertyDescriptor[retColl.Count]; + + retColl.CopyTo(propArray, 0); + + _collection = new PropertyDescriptorCollection(propArray, false); + } + + if (_collection?.Count > 0) + { + _propItems = _collection["Items"]; + if (_propItems is not null) + { + _collection.Remove(_propItems); + } + } + + return _collection!; + } +} diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripItemEditorForm.resx b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripItemEditorForm.resx new file mode 100644 index 00000000000..bf2513abf03 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/ToolStripItemEditorForm.resx @@ -0,0 +1,645 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Left, Right + + + + True + + + NoControl + + + + 84, 3 + + + 75, 23 + + + 1 + + + Cancel + + + btnCancel + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + okCancelTableLayoutPanel + + + 1 + + + Left, Right + + + True + + + None + + + NoControl + + + 3, 3 + + + No + + + 75, 23 + + + 0 + + + OK + + + btnOK + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + okCancelTableLayoutPanel + + + 0 + + + Top, Bottom, Left, Right + + + 3 + + + Left, Right + + + 2 + + + Left, Right + + + True + + + NoControl + + + 199, 3 + + + 69, 23 + + + 1 + + + &Add + + + btnAddNew + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addTableLayoutPanel + + + 0 + + + Left, Right + + + False + + + 3, 4 + + + 190, 21 + + + 0 + + + newItemTypes + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addTableLayoutPanel + + + 1 + + + 3, 17 + + + 1 + + + 271, 23 + + + 1 + + + addTableLayoutPanel + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="btnAddNew" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="newItemTypes" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0" /></TableLayoutSettings> + + + Right + + + True + + + 2 + + + 453, 310 + + + 1 + + + 162, 29 + + + 9 + + + okCancelTableLayoutPanel + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 1 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="btnOK" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="btnCancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="AutoSize,0" /></TableLayoutSettings> + + + Bottom, Left + + + True + + + NoControl + + + 3, 1 + + + 162, 13 + + + 0 + + + &Select item and add to list below: + + + lblItems + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 2 + + + Bottom, Left, Right + + + NoControl + + + 312, 0 + + + 303, 14 + + + 7 + + + toolStrip1 + + + selectedItemName + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 3 + + + Fill + + + False + + + 312, 17 + + + 303, 287 + + + 8 + + + selectedItemProps + + + System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 4 + + + True + + + 3, 43 + + + 53, 13 + + + 2 + + + &Members: + + + lblMembers + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 5 + + + Fill + + + 3, 59 + + + 271, 245 + + + 3 + + + listBoxItems + + + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 6 + + + Move the selected item up in the list + + + Move Up + + + Left + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAEdJREFUOE9jYBj0 + 4MCBA//JdiRU83+yDIFpBtoOcgFphqBrJskQXJqJMoSQZqIMgYU4RWEAMmQYGADzBsgrZCUkspMv3TUC + AGYzbEaI9u+YAAAAAElFTkSuQmCC + + + + NoControl + + + 280, 59 + + + 26, 23 + + + 4 + + + btnMoveUp + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 7 + + + Move the selected item down in the list + + + Move Down + + + Left + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAElJREFUOE9jYBje + 4MCBA/9hmGSfgjQCNcExlE+8OUPUAHRnI4cB0eFByBCiAhOXIURphsUTxbEAMghmCEk2o6cUijQTn+wo + UAkAY/VsRlvaylwAAAAASUVORK5CYII= + + + + NoControl + + + 280, 88 + + + 26, 23 + + + 5 + + + btnMoveDown + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 8 + + + Remove the selected item from the list + + + Remove + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAHdJREFUOE+tU1sO + wCAI8/434nRbMGPrFGldZsKHWkp5tfbHMbMjTOFz7I27Lv7Q7fU5sEGQBzcSrEgQNwVhJKVzqER5mI7k + jKlmalhtpsLvFJY6K90pWyrXoJJNSZScA7M9A1mHPo+yk6U7s5SXbBZLRVnGriKAJ50T5KPzn8IEAAAA + AElFTkSuQmCC + + + + NoControl + + + 280, 117 + + + 26, 23 + + + 6 + + + btnRemove + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel + + + 9 + + + 12, 12 + + + 7 + + + 618, 342 + + + 0 + + + tableLayoutPanel + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="addTableLayoutPanel" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="okCancelTableLayoutPanel" Row="6" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="lblItems" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="selectedItemName" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="selectedItemProps" Row="1" RowSpan="5" Column="2" ColumnSpan="1" /><Control Name="lblMembers" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="listBoxItems" Row="3" RowSpan="3" Column="0" ColumnSpan="1" /><Control Name="btnMoveUp" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="btnMoveDown" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="btnRemove" Row="5" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Percent,100,AutoSize,0" /></TableLayoutSettings> + + + True + + + 6, 13 + + + 642, 366 + + + 600, 400 + + + No + + + CenterScreen + + + Items Collection Editor + + + ToolStripItemEditorForm + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.cs.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.cs.xlf new file mode 100644 index 00000000000..3d3b633a0a7 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.cs.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.de.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.de.xlf new file mode 100644 index 00000000000..c71e8e9c80f --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.de.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.es.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.es.xlf new file mode 100644 index 00000000000..dd316cb5f07 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.es.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.fr.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.fr.xlf new file mode 100644 index 00000000000..96e0489f6eb --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.fr.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.it.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.it.xlf new file mode 100644 index 00000000000..673a526d906 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.it.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ja.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ja.xlf new file mode 100644 index 00000000000..ab035685d5d --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ja.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ko.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ko.xlf new file mode 100644 index 00000000000..27f689bd56a --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ko.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.pl.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.pl.xlf new file mode 100644 index 00000000000..a4ffbebf02d --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.pl.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.pt-BR.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.pt-BR.xlf new file mode 100644 index 00000000000..be7cc966588 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.pt-BR.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ru.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ru.xlf new file mode 100644 index 00000000000..a7997f459d1 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.ru.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.tr.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.tr.xlf new file mode 100644 index 00000000000..9e00071bcec --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.tr.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.zh-Hans.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.zh-Hans.xlf new file mode 100644 index 00000000000..4eb3c5edb63 --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.zh-Hans.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.zh-Hant.xlf b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.zh-Hant.xlf new file mode 100644 index 00000000000..b4409ee1c8b --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/xlf/ToolStripItemEditorForm.zh-Hant.xlf @@ -0,0 +1,72 @@ + + + + + + Items Collection Editor + Items Collection Editor + + + + &Add + &Add + + + + Cancel + Cancel + + + + Move the selected item down in the list + Move the selected item down in the list + + + + Move Down + Move Down + + + + Move the selected item up in the list + Move the selected item up in the list + + + + Move Up + Move Up + + + + OK + OK + + + + Remove the selected item from the list + Remove the selected item from the list + + + + Remove + Remove + + + + &Select item and add to list below: + &Select item and add to list below: + + + + &Members: + &Members: + + + + toolStrip1 + toolStrip1 + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EmbeddedResourceTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EmbeddedResourceTests.cs index 15a280c0c04..c3cc94f1e9b 100644 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EmbeddedResourceTests.cs +++ b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/EmbeddedResourceTests.cs @@ -123,6 +123,8 @@ public void EmbeddedResource_ResourcesExist_Bitmap(string resourceName) System.Windows.Forms.Design.ShortcutKeysEditor.resources System.Windows.Forms.Design.StringCollectionEditor.resources System.Windows.Forms.Design.StyleCollectionEditor.resources + System.Windows.Forms.Design.ToolStripItemEditorForm.resources + System.Windows.Forms.Design.BlankToolstrip.bmp """; [Fact] diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs index d309900bc3c..17b8c9a2149 100644 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs +++ b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs @@ -293,11 +293,19 @@ private void CreateDesignSurface(int n) rootComponent.BackColor = Color.Pink; rootComponent.Text = "Root Component hosted by the DesignSurface N.6"; - ToolStripContainer toolStripContainer = surface.CreateControl(new Size(800, 200), new Point(0, 0)); + ToolStripContainer toolStripContainer = surface.CreateControl(new Size(800, 200), new Point(0, 60)); toolStripContainer.Dock = DockStyle.Fill; - MenuStrip menuStrip1 = new(); - MenuStrip menuStrip2 = new(); + ToolStrip toolStrip1 = surface.CreateControl(new Size(400, 50), new Point(0, 0)); + ToolStripButton toolStripButton1 = new("toolStripButton1"); + ToolStripDropDownButton toolStripDropDownButton1 = new("toolStripDropDownButton1"); + ToolStripTextBox toolStripTextBox= new("toolStripTextBox"); + toolStrip1.Items.Add(toolStripButton1); + toolStrip1.Items.Add(toolStripDropDownButton1); + toolStrip1.Items.Add(toolStripTextBox); + + MenuStrip menuStrip1 = surface.CreateControl(new Size(400, 50), new Point(0, 60)); + MenuStrip menuStrip2 = surface.CreateControl(new Size(400, 50), new Point(0, 150)); ToolStripMenuItem toolStripMenuItem1 = new("TopMenuItem1"); ToolStripMenuItem toolStripMenuItem2 = new("TopMenuItem2"); diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs index 04eed97b21d..1ff089a64d9 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs @@ -32,7 +32,6 @@ public class DesignerAttributeTests $"System.Windows.Forms.Design.StatusBarDesigner, {Assemblies.SystemDesign}", $"System.Windows.Forms.Design.ToolBarButtonDesigner, {Assemblies.SystemDesign}", $"System.Windows.Forms.Design.ToolBarDesigner, {Assemblies.SystemDesign}", - $"System.Windows.Forms.Design.ToolStripCollectionEditor, {Assemblies.SystemDesign}", $"System.Windows.Forms.Design.ToolStripImageIndexEditor, {Assemblies.SystemDesign}", $"System.Windows.Forms.Design.WebBrowserDesigner, {Assemblies.SystemDesign}", ];