Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / ToolStripCollectionEditor.cs / 1 / ToolStripCollectionEditor.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="System.Windows.Forms.Design.ToolStripCollectionEditor..ctor()")] namespace System.Windows.Forms.Design { using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Windows.Forms; using System.Data; using System.Drawing.Design; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Design; using System.Windows.Forms.Layout; ////// Main class for collection editor for ToolStripItemCollections. Allows a single level of ToolStripItem children to be designed. /// internal class ToolStripCollectionEditor : CollectionEditor { ////// Default contstructor. /// public ToolStripCollectionEditor() : base(typeof(ToolStripItemCollection)) { } ////// Overridden to reation our editor form instead of the standard collection editor form. /// ///An instance of a ToolStripItemEditorForm protected override CollectionEditor.CollectionForm CreateCollectionForm() { return new ToolStripItemEditorForm(this); } ////// /// protected override string HelpTopic { get { return "net.ComponentModel.ToolStripCollectionEditor"; } } ///Gets the help topic to display for the dialog help button or pressing F1. Override to /// display a different help topic. ////// Check the owner... /// public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { // get ahold of the designer for the component that is launching this editor. If it // is a winbar, then we want to let it know this editor is up. // ToolStripDesigner designer = null; // see if the selected component is a winbar or winbar item that is directly on the form. // if (provider != null) { ISelectionService selectionService = (ISelectionService)provider.GetService(typeof(ISelectionService)); if (selectionService != null) { object primarySelection = selectionService.PrimarySelection; // if it's a drop down item, just pop up to it's owner. // if (primarySelection is ToolStripDropDownItem) { primarySelection = ((ToolStripDropDownItem)primarySelection).Owner; } // now get the designer. // if (primarySelection is ToolStrip) { IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost)); if (host != null) { designer = host.GetDesigner((IComponent)primarySelection) as ToolStripDesigner; } } } } try { if (designer != null) { designer.EditingCollection = true; } return base.EditValue(context, provider, value); } finally { if (designer != null) { designer.EditingCollection = false; } } } ////// Our internal form UI for the ToolStripItemCollectionEditor. /// protected class ToolStripItemEditorForm : CollectionEditor.CollectionForm { private ToolStripCollectionEditor editor = null; private const int ICON_HEIGHT = 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 ToolStripCustomTypeDescriptor toolStripCustomTypeDescriptor = null; ////// The amount of fudgespace we use when GDI+ returns us a string length. /// private const int GdiPlusFudge = 5; ////// The collection we're actually editing. /// private ToolStripItemCollection _targetToolStripCollection; ////// Our list of items that we're editing. /// private EditorItemCollection _itemList = null; ////// The start index of custom items in the new item type dropdown. /// int customItemIndex = -1; ////// All our control instance variables. /// private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; private System.Windows.Forms.TableLayoutPanel addTableLayoutPanel; private System.Windows.Forms.TableLayoutPanel okCancelTableLayoutPanel; private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnMoveUp; private System.Windows.Forms.Button btnMoveDown; private System.Windows.Forms.Label lblItems; private System.Windows.Forms.ComboBox newItemTypes; private System.Windows.Forms.Button btnAddNew; private CollectionEditor.FilterListBox listBoxItems; private System.Windows.Forms.Label selectedItemName; private System.Windows.Forms.Button btnRemove; private VsPropertyGrid selectedItemProps; private System.Windows.Forms.Label lblMembers; private IComponentChangeService _componentChangeSvc; private string _originalText = null; ////// Create the form and set it up. /// /// The collection editor that spawned us. internal ToolStripItemEditorForm(CollectionEditor parent) : base(parent) { this.editor = (ToolStripCollectionEditor)parent; InitializeComponent(); this.ActiveControl = listBoxItems; this._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 { /*FXCOP */ set { if (value != this._targetToolStripCollection) { // clear our existing list of items. // if (_itemList != null) { _itemList.Clear(); } // add any existing items to our list. // if (value != null) { if (Context != null) { // create a new list around the new value. // _itemList = new EditorItemCollection(this, listBoxItems.Items, value); ToolStrip realToolStrip = ToolStripFromObject(Context.Instance); _itemList.Add(realToolStrip); ToolStripItem itemInstance = Context.Instance as ToolStripItem; if (itemInstance != null && itemInstance.Site != null) { this.Text = _originalText + " (" + itemInstance.Site.Name + "." + Context.PropertyDescriptor.Name +")"; } foreach (ToolStripItem item in value) { if (item is DesignerToolStripControlHost) { continue; } _itemList.Add(item); } IComponentChangeService changeSvc = (IComponentChangeService)Context.GetService(typeof(IComponentChangeService)); if (changeSvc != null) { changeSvc.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged); } this.selectedItemProps.Site = new CollectionEditor.PropertyGridSite(Context, this.selectedItemProps); } } else { if (_componentChangeSvc != null) { _componentChangeSvc.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged); } _componentChangeSvc = null; this.selectedItemProps.Site = null; } _targetToolStripCollection = value; } } } private IComponentChangeService ComponentChangeService { get { if (_componentChangeSvc == null && Context != null) { _componentChangeSvc = (IComponentChangeService)Context.GetService(typeof(IComponentChangeService)); } return _componentChangeSvc; } } #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() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ToolStripItemEditorForm)); this.btnCancel = new System.Windows.Forms.Button(); this.btnOK = new System.Windows.Forms.Button(); this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.addTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.btnAddNew = new System.Windows.Forms.Button(); this.newItemTypes = new ImageComboBox(); this.okCancelTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.lblItems = new System.Windows.Forms.Label(); this.selectedItemName = new System.Windows.Forms.Label(); this.selectedItemProps = new VsPropertyGrid(Context /*IServiceProvider*/); this.lblMembers = new System.Windows.Forms.Label(); this.listBoxItems = new CollectionEditor.FilterListBox (); this.btnMoveUp = new System.Windows.Forms.Button(); this.btnMoveDown = new System.Windows.Forms.Button(); this.btnRemove = new System.Windows.Forms.Button(); this.tableLayoutPanel.SuspendLayout(); this.addTableLayoutPanel.SuspendLayout(); this.okCancelTableLayoutPanel.SuspendLayout(); this.SuspendLayout(); // // btnCancel // resources.ApplyResources(this.btnCancel, "btnCancel"); this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.btnCancel.Name = "btnCancel"; // // btnOK // resources.ApplyResources(this.btnOK, "btnOK"); this.btnOK.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0); this.btnOK.Name = "btnOK"; // // tableLayoutPanel // resources.ApplyResources(this.tableLayoutPanel, "tableLayoutPanel"); this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 274F)); this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel.Controls.Add(this.addTableLayoutPanel, 0, 1); this.tableLayoutPanel.Controls.Add(this.okCancelTableLayoutPanel, 0, 6); this.tableLayoutPanel.Controls.Add(this.lblItems, 0, 0); this.tableLayoutPanel.Controls.Add(this.selectedItemName, 2, 0); this.tableLayoutPanel.Controls.Add(this.selectedItemProps, 2, 1); this.tableLayoutPanel.Controls.Add(this.lblMembers, 0, 2); this.tableLayoutPanel.Controls.Add(this.listBoxItems, 0, 3); this.tableLayoutPanel.Controls.Add(this.btnMoveUp, 1, 3); this.tableLayoutPanel.Controls.Add(this.btnMoveDown, 1, 4); this.tableLayoutPanel.Controls.Add(this.btnRemove, 1, 5); this.tableLayoutPanel.Name = "tableLayoutPanel"; this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); // // addTableLayoutPanel // resources.ApplyResources(this.addTableLayoutPanel, "addTableLayoutPanel"); this.addTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.addTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.addTableLayoutPanel.Controls.Add(this.btnAddNew, 1, 0); this.addTableLayoutPanel.Controls.Add(this.newItemTypes, 0, 0); this.addTableLayoutPanel.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3); this.addTableLayoutPanel.Name = "addTableLayoutPanel"; this.addTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); // // btnAddNew // resources.ApplyResources(this.btnAddNew, "btnAddNew"); this.btnAddNew.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.btnAddNew.Name = "btnAddNew"; // // newItemTypes // resources.ApplyResources(this.newItemTypes, "newItemTypes"); this.newItemTypes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.newItemTypes.FormattingEnabled = true; this.newItemTypes.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0); this.newItemTypes.Name = "newItemTypes"; this.newItemTypes.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable; // // okCancelTableLayoutPanel // resources.ApplyResources(this.okCancelTableLayoutPanel, "okCancelTableLayoutPanel"); this.tableLayoutPanel.SetColumnSpan(this.okCancelTableLayoutPanel, 3); this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.okCancelTableLayoutPanel.Controls.Add(this.btnOK, 0, 0); this.okCancelTableLayoutPanel.Controls.Add(this.btnCancel, 1, 0); this.okCancelTableLayoutPanel.Margin = new System.Windows.Forms.Padding(3, 6, 0, 0); this.okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel"; this.okCancelTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); // // lblItems // resources.ApplyResources(this.lblItems, "lblItems"); this.lblItems.Margin = new System.Windows.Forms.Padding(0, 3, 3, 0); this.lblItems.Name = "lblItems"; // // selectedItemName // resources.ApplyResources(this.selectedItemName, "selectedItemName"); this.selectedItemName.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); this.selectedItemName.Name = "selectedItemName"; // // selectedItemProps // this.selectedItemProps.CommandsVisibleIfAvailable = false; resources.ApplyResources(this.selectedItemProps, "selectedItemProps"); this.selectedItemProps.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); this.selectedItemProps.Name = "selectedItemProps"; this.tableLayoutPanel.SetRowSpan(this.selectedItemProps, 5); // // lblMembers // resources.ApplyResources(this.lblMembers, "lblMembers"); this.lblMembers.Margin = new System.Windows.Forms.Padding(0, 3, 3, 0); this.lblMembers.Name = "lblMembers"; // // listBoxItems // resources.ApplyResources(this.listBoxItems, "listBoxItems"); this.listBoxItems.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable; this.listBoxItems.FormattingEnabled = true; this.listBoxItems.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3); this.listBoxItems.Name = "listBoxItems"; this.tableLayoutPanel.SetRowSpan(this.listBoxItems, 3); this.listBoxItems.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; // // btnMoveUp // resources.ApplyResources(this.btnMoveUp, "btnMoveUp"); this.btnMoveUp.Margin = new System.Windows.Forms.Padding(3, 3, 18, 0); this.btnMoveUp.Name = "btnMoveUp"; // // btnMoveDown // resources.ApplyResources(this.btnMoveDown, "btnMoveDown"); this.btnMoveDown.Margin = new System.Windows.Forms.Padding(3, 1, 18, 3); this.btnMoveDown.Name = "btnMoveDown"; // // btnRemove // resources.ApplyResources(this.btnRemove, "btnRemove"); this.btnRemove.Margin = new System.Windows.Forms.Padding(3, 3, 18, 3); this.btnRemove.Name = "btnRemove"; // // ToolStripCollectionEditor // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AcceptButton = this.btnOK; resources.ApplyResources(this, "$this"); this.CancelButton = this.btnCancel; this.Controls.Add(this.tableLayoutPanel); this.HelpButton = true; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ToolStripCollectionEditor"; this.Padding = new System.Windows.Forms.Padding(9); this.ShowIcon = false; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; this.tableLayoutPanel.ResumeLayout(false); this.tableLayoutPanel.PerformLayout(); this.addTableLayoutPanel.ResumeLayout(false); this.addTableLayoutPanel.PerformLayout(); this.okCancelTableLayoutPanel.ResumeLayout(false); this.okCancelTableLayoutPanel.PerformLayout(); this.ResumeLayout(false); //events this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.ToolStripCollectionEditor_HelpButtonClicked); this.newItemTypes.DropDown += new System.EventHandler(this.OnnewItemTypes_DropDown); this.newItemTypes.HandleCreated += new EventHandler(OnComboHandleCreated); this.newItemTypes.SelectedIndexChanged += new System.EventHandler(this.OnnewItemTypes_SelectedIndexChanged); this.btnAddNew.Click += new System.EventHandler(this.OnnewItemTypes_SelectionChangeCommitted); this.btnMoveUp.Click += new System.EventHandler(this.OnbtnMoveUp_Click); this.btnMoveDown.Click += new System.EventHandler(this.OnbtnMoveDown_Click); this.btnRemove.Click += new System.EventHandler(this.OnbtnRemove_Click); this.btnOK.Click += new System.EventHandler(this.OnbtnOK_Click); this.selectedItemName.Paint += new System.Windows.Forms.PaintEventHandler(this.OnselectedItemName_Paint); this.listBoxItems.SelectedIndexChanged += new System.EventHandler(this.OnlistBoxItems_SelectedIndexChanged); this.listBoxItems.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.OnlistBoxItems_DrawItem); this.listBoxItems.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.OnlistBoxItems_MeasureItem); this.selectedItemProps.PropertyValueChanged += new PropertyValueChangedEventHandler(this.PropertyGrid_propertyValueChanged); this.Load += new System.EventHandler(this.OnFormLoad); } #endregion private void OnComboHandleCreated(object sender, EventArgs e){ // this.newItemTypes.HandleCreated -= new EventHandler(OnComboHandleCreated); this.newItemTypes.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.OnlistBoxItems_MeasureItem); this.newItemTypes.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.OnlistBoxItems_DrawItem); } ////// Add a new item to our list. This will add a preview item /// and a listbox 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) { throw new IndexOutOfRangeException(); } _itemList.Insert(index, newItem); } ToolStrip ownerToolStrip = (Context != null) ? ToolStripFromObject(Context.Instance) : null; if (ownerToolStrip != null) { // set the owner to be the real winbar 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") { this.lblItems.Invalidate(); } } ////// Pick up the new collection value. /// protected override void OnEditValueChanged() { this.selectedItemProps.SelectedObjects = null; Collection = (ToolStripItemCollection)EditValue; } ////// Called when the form loads...add the types from the list into the combo box. /// /// /// private void OnFormLoad(System.Object sender, System.EventArgs e) { // Set the font as appropriate. this.newItemTypes.ItemHeight = Math.Max(ICON_HEIGHT, Font.Height); Component component = Context.Instance as Component; Debug.Assert(component != null, "why isnt the editor instance a component?"); if (component != null) { Type[] newToolStripItemTypes = ToolStripDesignerUtils.GetStandardItemTypes(component); newItemTypes.Items.Clear(); foreach (Type t in newToolStripItemTypes){ this.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){ this.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(System.Object sender, System.EventArgs e) { DialogResult = DialogResult.OK; //VSWhidbey 456449 - we dont need to call Hide here DialogResult does it for us.... } private void ToolStripCollectionEditor_HelpButtonClicked(object sender, CancelEventArgs e) { e.Cancel = true; editor.ShowHelp(); } ////// Remove all the selected items. /// private void OnbtnRemove_Click(System.Object sender, System.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(System.Object sender, System.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(System.Object sender, System.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(System.Object sender, System.EventArgs e) { if (newItemTypes.Tag == null || (bool)newItemTypes.Tag == false) { 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 + GdiPlusFudge); dropDownHeight += (Font.Height + SEPARATOR_HEIGHT) +2*IMAGE_PADDING; } } 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 winbar. /// /// /// // Okay to not catch non-CLS compliant exceptions [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] private void OnnewItemTypes_SelectionChangeCommitted(System.Object sender, System.EventArgs e) { // get the item type // TypeListItem typeItem = newItemTypes.SelectedItem as TypeListItem; if (typeItem != null) { // Create the item ToolStripItem newItem = (ToolStripItem)CreateInstance(typeItem.Type); //Set the Image property and DisplayStyle... if (newItem is ToolStripButton || newItem is ToolStripSplitButton || newItem is ToolStripDropDownButton) { Image image = null; try { image = new Bitmap(typeof(ToolStripButton), "blank.bmp"); } catch (Exception ex) { if (ClientUtils.IsCriticalException(ex)) { throw; } } PropertyDescriptor imageProperty = TypeDescriptor.GetProperties(newItem)["Image"]; Debug.Assert(imageProperty != null, "Could not find 'Image' property in ToolStripItem."); if (imageProperty != null && image != null) { imageProperty.SetValue(newItem, image); } PropertyDescriptor dispProperty = TypeDescriptor.GetProperties(newItem)["DisplayStyle"]; Debug.Assert(dispProperty != null, "Could not find 'DisplayStyle' property in ToolStripItem."); if (dispProperty != null) { dispProperty.SetValue(newItem, ToolStripItemDisplayStyle.Image); } PropertyDescriptor imageTransProperty = TypeDescriptor.GetProperties(newItem)["ImageTransparentColor"]; Debug.Assert(imageTransProperty != null, "Could not find 'ImageTransparentColor' property in ToolStripItem."); if (imageTransProperty != null) { imageTransProperty.SetValue(newItem, Color.Magenta); } } // add it. // AddItem(newItem, -1); listBoxItems.Focus(); } } ////// Just invalidate the combo on a selection change. /// private void OnnewItemTypes_SelectedIndexChanged(System.Object sender, System.EventArgs e) { newItemTypes.Invalidate(); } ////// Custom measureItem for the ListBox items... /// private void OnlistBoxItems_MeasureItem(object sender, MeasureItemEventArgs e) { int separatorHeight = 0; if (sender is ComboBox) { bool drawSeparator = e.Index == customItemIndex; if (e.Index >=0 && drawSeparator) { separatorHeight = SEPARATOR_HEIGHT; } } Font measureFont = this.Font; e.ItemHeight = Math.Max(ICON_HEIGHT + separatorHeight, measureFont.Height + separatorHeight) +2*IMAGE_PADDING; } ////// Custom draw the list box item with the icon and the text. We actually share this code b/t the list box and the combobox. /// private void OnlistBoxItems_DrawItem(System.Object sender, System.Windows.Forms.DrawItemEventArgs e) { // okay, nevermind. // 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 = null; string itemText = null; bool indentItem = false; bool drawSeparator = false; bool isComboEditBox = ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit); if (sender is ListBox) { ListBox listBox = sender as ListBox; // the list box has the items directly. // Component item = listBox.Items[e.Index] as Component; if (item == null) { Debug.Fail("Unexpected listbox item painted!"); return; } if (item is ToolStripItem) { indentItem = true; } itemType = item.GetType(); itemText = (item.Site != null) ? item.Site.Name : itemType.Name; } else if (sender is ComboBox) { // the combobox has just the types. // drawSeparator = ((e.Index == customItemIndex) && !isComboEditBox); // never draw the separator in the edit box, even if it is the selected index. TypeListItem typeListItem = ((ComboBox)sender).Items[e.Index] as TypeListItem; if (typeListItem == null) { Debug.Fail("Unexpected combobox item!"); return; } itemType = typeListItem.Type; itemText = typeListItem.ToString(); } else { Debug.Fail("Unexpected sender, who's calling DrawItem"); return; } // okay, we've got ourselves an item type. draw it. // if (itemType != null) { Color textColor = Color.Empty; 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 Size(ICON_HEIGHT, ICON_HEIGHT); int xOffset = (isComboEditBox) ? 0 : IMAGE_PADDING*2; imageBounds.Offset(xOffset,IMAGE_PADDING); if (drawSeparator) { imageBounds.Offset(0,SEPARATOR_HEIGHT); } if (indentItem) { imageBounds.X += ICON_HEIGHT+INDENT_SPACING; } // make sure after all this we stil 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 != null) { if (isComboEditBox) { // Paint the icon of the combo's textbox area. e.Graphics.DrawImage(tbxBitmap, e.Bounds.X, e.Bounds.Y, ICON_HEIGHT, ICON_HEIGHT); } else { e.Graphics.FillRectangle(SystemBrushes.Window, imageBounds); e.Graphics.DrawImage(tbxBitmap, imageBounds); } } // calculate the text rect Rectangle textBounds = e.Bounds; textBounds.X = imageBounds.Right + TEXT_IMAGE_SPACING; textBounds.Y = imageBounds.Top-IMAGE_PADDING; if (!isComboEditBox) { textBounds.Y+=IMAGE_PADDING*2; } textBounds.Intersect(e.Bounds); // draw the background as necessary. Rectangle fillBounds = e.Bounds; fillBounds.X = textBounds.X -2; if (drawSeparator) { fillBounds.Y += SEPARATOR_HEIGHT; fillBounds.Height -= SEPARATOR_HEIGHT; } 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, this.Font, textBounds, textColor, format); } // finally, draw the focusrect. // 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(System.Object sender, System.EventArgs e) { // push the items into the grid. // object[] objList = new object[listBoxItems.SelectedItems.Count]; if (objList.Length > 0) { listBoxItems.SelectedItems.CopyTo(objList, 0); } // ToolStrip is selected ... remove the items property if (objList.Length == 1 && objList[0] is ToolStrip) { ToolStrip parentStrip = objList[0] as ToolStrip; if (parentStrip != null && parentStrip.Site != null) { if (toolStripCustomTypeDescriptor == null) { toolStripCustomTypeDescriptor = new ToolStripCustomTypeDescriptor((ToolStrip)objList[0]); } this.selectedItemProps.SelectedObjects = new object[]{toolStripCustomTypeDescriptor}; } else { // if null parentStrip or non sited then dont show the properties... this.selectedItemProps.SelectedObjects = null; } } else { this.selectedItemProps.SelectedObjects = objList; } // 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); this.btnRemove.Enabled = objList.Length > 0; // Cannot remove a Winbar thru this CollectionEditor.... foreach (object obj in listBoxItems.SelectedItems) { if (obj is ToolStrip) { btnRemove.Enabled = btnMoveUp.Enabled = btnMoveDown.Enabled = false; break; } } // invalidate the listbox and the label above the grid. // listBoxItems.Invalidate(); selectedItemName.Invalidate(); } ////// Invalidate the ListBox and the SelectedItemName Label on top of the propertyGrid /// private void PropertyGrid_propertyValueChanged(object sender, PropertyValueChangedEventArgs e) { // invalidate the listbox 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. /// [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters")] private void OnselectedItemName_Paint(System.Object sender, System.Windows.Forms.PaintEventArgs e) { // make the bolded font for the type name. // using (Font boldFont = new Font(selectedItemName.Font, FontStyle.Bold)) { Label label = sender as Label; Rectangle bounds = label.ClientRectangle; StringFormat stringFormat = null; bool rightToLeft = (label.RightToLeft == RightToLeft.Yes); if (rightToLeft) { stringFormat = new StringFormat(StringFormatFlags.DirectionRightToLeft); } else { stringFormat = new StringFormat(); } stringFormat.HotkeyPrefix = System.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 classname in bold, then the item name. // Component selectedItem = null; if (listBoxItems.SelectedItem is ToolStrip) { selectedItem = (ToolStrip)listBoxItems.SelectedItem; } else { selectedItem = (ToolStripItem)listBoxItems.SelectedItem; } string className = "&" +selectedItem.GetType().Name; if (selectedItem.Site != null) { e.Graphics.FillRectangle(SystemBrushes.Control , bounds); // erase background string itemName = selectedItem.Site.Name; if (label != 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); //e.Graphics.DrawString(itemName, selectedItemName.Font, SystemBrushes.WindowText, new Rectangle(classWidth + GdiPlusFudge, 0, bounds.Width, bounds.Height)); int itemTextWidth =(int)e.Graphics.MeasureString(itemName, selectedItemName.Font).Width; Rectangle textRect = new Rectangle(classWidth + GdiPlusFudge, 0, bounds.Width - (classWidth + GdiPlusFudge), bounds.Height); if (itemTextWidth > textRect.Width) { label.AutoEllipsis = true; } else { label.AutoEllipsis = false; } TextFormatFlags flags = TextFormatFlags.EndEllipsis; if (rightToLeft) { flags |= TextFormatFlags.RightToLeft; } TextRenderer.DrawText(e.Graphics, itemName, selectedItemName.Font, textRect, SystemColors.WindowText, flags); } break; case 0: e.Graphics.FillRectangle(SystemBrushes.Control , bounds); // erase background if (label != null) { label.Text = SR.GetString(SR.ToolStripItemCollectionEditorLabelNone); } e.Graphics.DrawString(SR.GetString(SR.ToolStripItemCollectionEditorLabelNone), boldFont, SystemBrushes.WindowText, bounds, stringFormat); break; default: e.Graphics.FillRectangle(SystemBrushes.Control , bounds); // erase background if (label != null) { label.Text = SR.GetString(SR.ToolStripItemCollectionEditorLabelMultipleItems); } e.Graphics.DrawString(SR.GetString(SR.ToolStripItemCollectionEditorLabelMultipleItems), boldFont, SystemBrushes.WindowText, bounds, stringFormat); break; } } } ////// Removes an item from the list and the preview winbar, as /// /// private void RemoveItem(ToolStripItem item) { int index; try { // remove the item from the list. // index = _itemList.IndexOf(item); _itemList.Remove(item); // destroy the item. This will remove it from the // designer as well. // } 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 ToolStripDropDownItem /// internal static ToolStrip ToolStripFromObject(object instance) { ToolStrip currentToolStrip = null; if (instance != null) { if (instance is ToolStripDropDownItem) { currentToolStrip = ((ToolStripDropDownItem)instance).DropDown; } else { currentToolStrip = instance as ToolStrip; } } return currentToolStrip; } private class ImageComboBox : ComboBox { public ImageComboBox() { } private Rectangle ImageRect { get { // Need to add padding for RTL combobox. if (RightToLeft == RightToLeft.Yes) { return new Rectangle(4 + SystemInformation.HorizontalScrollBarThumbWidth, 3, ICON_HEIGHT, ICON_HEIGHT); } return new Rectangle(3, 3, ICON_HEIGHT, ICON_HEIGHT); } } 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.Msg) { case NativeMethods.WM_SETFOCUS: case NativeMethods.WM_KILLFOCUS: Invalidate(ImageRect); break; } } } ////// This is a magic collection. It's job is to keep the preview winbar and the listbox in sync and manage both sets of items. /// It contains a list of EditorItem objects, which whold the information for each item, and a reference to the real ToolStripItem component, /// the and the preview ToolStripItem. The order and contents of this combobox always match that of the real collection, the list box, and the preview winbar. /// /// It operates generically on three ILists: the listbox.Items collection, the previewToolStrip.Items collection, and the actual ToolStripItemCollection being designed. /// private class EditorItemCollection : CollectionBase { private IList _listBoxList; // the ListBox.Items collection private IList _targetCollectionList; // the real deal target collection private ToolStripItemEditorForm _owner; // the owner form that created this collection. ////// Setup the collection's variables. /// internal EditorItemCollection(ToolStripItemEditorForm owner, IList displayList, IList componentList) { _owner = owner; _listBoxList = displayList; _targetCollectionList = componentList; } ////// Add a new winbaritem. 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 != null) { return; } try { _owner.Context.OnComponentChanging(); // yank 'em all outta 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 doesnt contain the ToolStrip. _targetCollectionList.Insert(toIndex -1, editorItem.Component); InnerList.Insert(toIndex, editorItem); } finally { _owner.Context.OnComponentChanged(); } } ////// Clear has a differnet semantic than remove. Clear simply dumps all the items /// out of the listbox 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) { EditorItem item = (EditorItem)value; if (item.Host != null) { // insert into the listbox // _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 listbox 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) { EditorItem editorItem = (EditorItem)List[index]; // pull it from the listbox 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 cleansup the // preview item. // editorItem.Dispose(); base.OnRemove (index, value); } ////// Remove an item. See OnRemove for the gory details. /// /// public void Remove(ToolStripItem item) { int index = IndexOf(item); List.RemoveAt(index); } ////// This class keeps track of the mapping between a winbaritem in the designer, in the /// preview winbar, and in the listbox. /// private class EditorItem { public ToolStripItem _component; // the real deal item in the designer. public ToolStrip _host; ////// Yes yes, it's a ctor. /// internal EditorItem(object componentItem) { if (componentItem is ToolStrip) { _host = (ToolStrip)componentItem; } else { _component = (ToolStripItem)componentItem; } } ////// The item that's actually being created in the designer. /// public ToolStripItem Component { get { return _component; } } ////// The ToolStrip that's actually being created in the designer. /// public ToolStrip Host { get { return _host; } } ////// Cleanup our mess. /// public void Dispose() { GC.SuppressFinalize(this); this._component = null; } } } private class TypeListItem { public readonly Type Type; public TypeListItem(Type t) { Type = t; } public override string ToString() { return ToolStripDesignerUtils.GetToolboxDescription(Type); } } } } } // 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
- TableLayoutPanel.cs
- FixedFlowMap.cs
- _DigestClient.cs
- OleDbDataReader.cs
- EntityConnectionStringBuilder.cs
- MemberAccessException.cs
- XmlNavigatorStack.cs
- XamlFigureLengthSerializer.cs
- InstancePersistence.cs
- PreviewPageInfo.cs
- OleTxTransactionInfo.cs
- DataBindingExpressionBuilder.cs
- EpmCustomContentDeSerializer.cs
- DependsOnAttribute.cs
- CallbackTimeoutsElement.cs
- LinqDataSourceStatusEventArgs.cs
- XmlObjectSerializerReadContextComplexJson.cs
- PersonalizationDictionary.cs
- InkCanvasFeedbackAdorner.cs
- SystemColorTracker.cs
- ObjectDataSource.cs
- IProvider.cs
- NativeMethods.cs
- CompoundFileIOPermission.cs
- SchemaImporter.cs
- Int32RectValueSerializer.cs
- Int32Storage.cs
- SizeIndependentAnimationStorage.cs
- DrawItemEvent.cs
- CompatibleComparer.cs
- DataGridViewAutoSizeModeEventArgs.cs
- storepermissionattribute.cs
- ClientSponsor.cs
- Activator.cs
- StringKeyFrameCollection.cs
- XmlWellformedWriter.cs
- TextEvent.cs
- StreamReader.cs
- FlowchartDesigner.Helpers.cs
- SamlAuthorityBinding.cs
- AdjustableArrowCap.cs
- ExceptionRoutedEventArgs.cs
- HttpCookie.cs
- RegionData.cs
- KnowledgeBase.cs
- SafeNativeMethods.cs
- ConfigurationManagerHelperFactory.cs
- ApplicationId.cs
- NotConverter.cs
- PrtTicket_Editor.cs
- HttpApplication.cs
- XMLSchema.cs
- AdapterDictionary.cs
- ScrollPattern.cs
- HttpEncoderUtility.cs
- XamlClipboardData.cs
- FastEncoder.cs
- DataSourceControl.cs
- MemberProjectionIndex.cs
- ShapeTypeface.cs
- WrapPanel.cs
- SRef.cs
- DataColumn.cs
- ConfigPathUtility.cs
- TextTreeNode.cs
- XslCompiledTransform.cs
- lengthconverter.cs
- ActivityInterfaces.cs
- InputProcessorProfiles.cs
- DataSourceHelper.cs
- HitTestDrawingContextWalker.cs
- XmlImplementation.cs
- UTF7Encoding.cs
- ResourceDisplayNameAttribute.cs
- WebMessageEncodingElement.cs
- PropertyMappingExceptionEventArgs.cs
- tibetanshape.cs
- ConfigurationValues.cs
- SQLDateTime.cs
- PointConverter.cs
- SqlDependencyUtils.cs
- AsymmetricKeyExchangeDeformatter.cs
- SoapAttributeAttribute.cs
- DrawingImage.cs
- CompiledIdentityConstraint.cs
- XmlReaderDelegator.cs
- WinFormsSpinner.cs
- DialogBaseForm.cs
- SQLInt16.cs
- AliasGenerator.cs
- DataMember.cs
- DataSourceControl.cs
- DefaultTextStoreTextComposition.cs
- MonthChangedEventArgs.cs
- PtsPage.cs
- TextServicesHost.cs
- ContentDefinition.cs
- DesignerVerbCollection.cs
- Point.cs
- ContextDataSource.cs