Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / WinForms / Managed / System / WinForms / ToolStripDropDownItem.cs / 1 / ToolStripDropDownItem.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System; using System.Drawing; using System.Windows.Forms; using System.ComponentModel; using System.Diagnostics; using System.Security.Permissions; using System.Windows.Forms.Layout; ////// /// Base class for ToolStripItems that display DropDown windows. /// [Designer("System.Windows.Forms.Design.ToolStripMenuItemDesigner, " + AssemblyRef.SystemDesign)] [DefaultProperty("DropDownItems")] public abstract class ToolStripDropDownItem : ToolStripItem { private ToolStripDropDown dropDown = null; private ToolStripDropDownDirection toolStripDropDownDirection = ToolStripDropDownDirection.Default; private static readonly object EventDropDownShow = new object(); private static readonly object EventDropDownHide = new object(); private static readonly object EventDropDownOpened = new object(); private static readonly object EventDropDownClosed = new object(); private static readonly object EventDropDownItemClicked = new object(); ////// /// Protected ctor so you can't create one of these without deriving from it. /// protected ToolStripDropDownItem() { } protected ToolStripDropDownItem(string text, Image image, EventHandler onClick) : base(text, image, onClick) { } protected ToolStripDropDownItem(string text, Image image, EventHandler onClick, string name) : base(text, image, onClick, name) { } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] protected ToolStripDropDownItem(string text, Image image, params ToolStripItem[] dropDownItems) : this(text, image, (EventHandler)null) { if (dropDownItems != null) { this.DropDownItems.AddRange(dropDownItems); } } ////// /// The ToolStripDropDown that will be displayed when this item is clicked. /// [ TypeConverter(typeof(ReferenceConverter)), SRCategory(SR.CatData), SRDescription(SR.ToolStripDropDownDescr) ] public ToolStripDropDown DropDown { get { if (dropDown == null) { DropDown = CreateDefaultDropDown(); if (!(this is ToolStripOverflowButton)) { dropDown.SetAutoGeneratedInternal(true); } } return dropDown; } set { if (dropDown != value) { if (dropDown != null) { dropDown.Opened -= new EventHandler(DropDown_Opened); dropDown.Closed -= new ToolStripDropDownClosedEventHandler(DropDown_Closed); dropDown.ItemClicked -= new ToolStripItemClickedEventHandler(DropDown_ItemClicked); dropDown.UnassignDropDownItem(); } dropDown = value; if (dropDown != null) { dropDown.Opened += new EventHandler(DropDown_Opened); dropDown.Closed += new ToolStripDropDownClosedEventHandler(DropDown_Closed); dropDown.ItemClicked += new ToolStripItemClickedEventHandler(DropDown_ItemClicked); dropDown.AssignToDropDownItem(); } } } } // the area which activates the dropdown. internal virtual Rectangle DropDownButtonArea { get { return this.Bounds; } } [Browsable(false)] [SRDescription(SR.ToolStripDropDownItemDropDownDirectionDescr)] [SRCategory(SR.CatBehavior)] public ToolStripDropDownDirection DropDownDirection { get { if (toolStripDropDownDirection == ToolStripDropDownDirection.Default) { ToolStrip parent = ParentInternal; if (parent != null) { ToolStripDropDownDirection dropDownDirection = parent.DefaultDropDownDirection; if (OppositeDropDownAlign || this.RightToLeft != parent.RightToLeft && (this.RightToLeft != RightToLeft.Inherit)) { dropDownDirection = RTLTranslateDropDownDirection(dropDownDirection, RightToLeft); } if (IsOnDropDown) { // we gotta make sure that we dont collide with the existing menu. Rectangle bounds = GetDropDownBounds(dropDownDirection); Rectangle ownerItemBounds = new Rectangle(TranslatePoint(Point.Empty, ToolStripPointType.ToolStripItemCoords, ToolStripPointType.ScreenCoords), Size); Rectangle intersectionBetweenChildAndParent = Rectangle.Intersect(bounds, ownerItemBounds); // grab the intersection if (intersectionBetweenChildAndParent.Width >= 2) { RightToLeft toggledRightToLeft = (RightToLeft == RightToLeft.Yes) ? RightToLeft.No : RightToLeft.Yes; ToolStripDropDownDirection newDropDownDirection = RTLTranslateDropDownDirection(dropDownDirection, toggledRightToLeft); // verify that changing the dropdown direction actually causes less intersection. int newIntersectionWidth = Rectangle.Intersect(GetDropDownBounds(newDropDownDirection), ownerItemBounds).Width; if (newIntersectionWidth < intersectionBetweenChildAndParent.Width) { dropDownDirection = newDropDownDirection; } } } return dropDownDirection; } } // someone has set a custom override return toolStripDropDownDirection; } set { // cant use Enum.IsValid as its not sequential switch (value) { case ToolStripDropDownDirection.AboveLeft: case ToolStripDropDownDirection.AboveRight: case ToolStripDropDownDirection.BelowLeft: case ToolStripDropDownDirection.BelowRight: case ToolStripDropDownDirection.Left: case ToolStripDropDownDirection.Right: case ToolStripDropDownDirection.Default: break; default: throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolStripDropDownDirection)); } if (toolStripDropDownDirection != value) { toolStripDropDownDirection = value; if (HasDropDownItems && DropDown.Visible) { DropDown.Location = DropDownLocation; } } } } ////// /// Occurs when the dropdown is closed /// [ SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownClosedDecr) ] public event EventHandler DropDownClosed { add { Events.AddHandler(EventDropDownClosed, value); } remove { Events.RemoveHandler(EventDropDownClosed, value); } } ///internal protected virtual Point DropDownLocation { get { if (ParentInternal == null || !HasDropDownItems){ return Point.Empty; } ToolStripDropDownDirection dropDownDirection = DropDownDirection; return GetDropDownBounds(dropDownDirection).Location; } } /// [ SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpeningDescr) ] public event EventHandler DropDownOpening { add { Events.AddHandler(EventDropDownShow, value); } remove { Events.RemoveHandler(EventDropDownShow, value); } } /// /// /// Occurs when the dropdown is opened /// [ SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpenedDescr) ] public event EventHandler DropDownOpened { add { Events.AddHandler(EventDropDownOpened, value); } remove { Events.RemoveHandler(EventDropDownOpened, value); } } ////// /// Returns the DropDown's items collection. /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Content), SRCategory(SR.CatData), SRDescription(SR.ToolStripDropDownItemsDescr) ] public ToolStripItemCollection DropDownItems { get { return DropDown.Items; } } ////// /// Occurs when the dropdown is opened /// [SRCategory(SR.CatAction)] public event ToolStripItemClickedEventHandler DropDownItemClicked { add { Events.AddHandler(EventDropDownItemClicked, value); } remove { Events.RemoveHandler(EventDropDownItemClicked, value); } } ///[Browsable(false)] public virtual bool HasDropDownItems { get { //VSWhidbey 354665: use count of visible DisplayedItems instead so that we take into account things that arent visible return (dropDown != null) && dropDown.HasVisibleItems; } } internal bool HasDropDown { get { return dropDown != null; } } /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override bool Pressed { get { // if (dropDown != null) { if (DropDown.AutoClose || !IsInDesignMode || (IsInDesignMode && !IsOnDropDown)){ return DropDown.OwnerItem == this && DropDown.Visible; } } return base.Pressed; } } internal virtual bool OppositeDropDownAlign { get { return false; } } internal virtual void AutoHide(ToolStripItem otherItemBeingSelected) { HideDropDown(); } /// protected override AccessibleObject CreateAccessibilityInstance() { return new ToolStripDropDownItemAccessibleObject(this); } /// protected virtual ToolStripDropDown CreateDefaultDropDown() { // AutoGenerate a Winbar DropDown - set the property so we hook events return new ToolStripDropDown(this, true); } private Rectangle DropDownDirectionToDropDownBounds(ToolStripDropDownDirection dropDownDirection, Rectangle dropDownBounds) { Point offset = Point.Empty; switch (dropDownDirection) { case ToolStripDropDownDirection.AboveLeft: offset.X = - dropDownBounds.Width + this.Width; offset.Y = - dropDownBounds.Height+1; break; case ToolStripDropDownDirection.AboveRight: offset.Y = - dropDownBounds.Height+1; break; case ToolStripDropDownDirection.BelowRight: offset.Y = this.Height-1; break; case ToolStripDropDownDirection.BelowLeft: offset.X = - dropDownBounds.Width + this.Width; offset.Y = this.Height-1; break; case ToolStripDropDownDirection.Right: offset.X = this.Width; if (!IsOnDropDown) { // overlap the toplevel toolstrip offset.X -=1; } break; case ToolStripDropDownDirection.Left: offset.X = - dropDownBounds.Width; break; } Point itemScreenLocation = this.TranslatePoint(Point.Empty, ToolStripPointType.ToolStripItemCoords, ToolStripPointType.ScreenCoords); dropDownBounds.Location = new Point(itemScreenLocation.X + offset.X, itemScreenLocation.Y + offset.Y); dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(dropDownBounds); return dropDownBounds; } private void DropDown_Closed(object sender, ToolStripDropDownClosedEventArgs e) { OnDropDownClosed(EventArgs.Empty); } private void DropDown_Opened(object sender, EventArgs e) { OnDropDownOpened(EventArgs.Empty); } private void DropDown_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { OnDropDownItemClicked(e); } /// /// /// Make sure we unhook dropdown events. /// protected override void Dispose(bool disposing) { if (this.dropDown != null) { dropDown.Opened -= new EventHandler(DropDown_Opened); dropDown.Closed -= new ToolStripDropDownClosedEventHandler(DropDown_Closed); dropDown.ItemClicked -= new ToolStripItemClickedEventHandler(DropDown_ItemClicked); if (disposing && dropDown.IsAutoGenerated) { // if we created the dropdown, dispose it and its children. dropDown.Dispose(); dropDown = null; } } base.Dispose(disposing); } private Rectangle GetDropDownBounds(ToolStripDropDownDirection dropDownDirection) { Rectangle dropDownBounds = new Rectangle(Point.Empty, DropDown.GetSuggestedSize()); // calculate the offset from the upper left hand corner of the item. dropDownBounds = DropDownDirectionToDropDownBounds(dropDownDirection, dropDownBounds); // we should make sure we dont obscure the owner item. Rectangle itemScreenBounds = new Rectangle(this.TranslatePoint(Point.Empty, ToolStripPointType.ToolStripItemCoords, ToolStripPointType.ScreenCoords), this.Size); if (Rectangle.Intersect(dropDownBounds, itemScreenBounds).Height > 1) { bool rtl = (RightToLeft == RightToLeft.Yes); // try positioning to the left if (Rectangle.Intersect(dropDownBounds, itemScreenBounds).Width > 1) { dropDownBounds = DropDownDirectionToDropDownBounds(!rtl ? ToolStripDropDownDirection.Right : ToolStripDropDownDirection.Left, dropDownBounds); } // try positioning to the right if (Rectangle.Intersect(dropDownBounds, itemScreenBounds).Width > 1) { dropDownBounds = DropDownDirectionToDropDownBounds(!rtl ? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right, dropDownBounds); } } return dropDownBounds; } ////// /// Hides the DropDown, if it is visible. /// public void HideDropDown() { // consider - CloseEventArgs to prevent shutting down. OnDropDownHide(EventArgs.Empty); if (this.dropDown != null && this.dropDown.Visible) { DropDown.Visible = false; } } protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); if (dropDown != null) { dropDown.OnOwnerItemFontChanged(EventArgs.Empty); } } ///protected override void OnBoundsChanged() { base.OnBoundsChanged(); //Reset the Bounds... if (this.dropDown != null && this.dropDown.Visible) { this.dropDown.Bounds = GetDropDownBounds(DropDownDirection); } } protected override void OnRightToLeftChanged(EventArgs e) { base.OnRightToLeftChanged(e); if (HasDropDownItems) { // only perform a layout on a visible dropdown - otherwise clear the preferred size cache. if (DropDown.Visible) { LayoutTransaction.DoLayout(DropDown, this, PropertyNames.RightToLeft); } else { CommonProperties.xClearPreferredSizeCache(DropDown); DropDown.LayoutRequired = true; } } } internal override void OnImageScalingSizeChanged(EventArgs e) { base.OnImageScalingSizeChanged(e); if (HasDropDown && DropDown.IsAutoGenerated) { DropDown.DoLayoutIfHandleCreated(new ToolStripItemEventArgs(this)); } } /// /// /// Called as a response to HideDropDown /// protected virtual void OnDropDownHide(EventArgs e) { this.Invalidate(); EventHandler handler = (EventHandler)Events[EventDropDownHide]; if (handler != null) handler(this, e); } ////// /// Last chance to stick in the DropDown before it is shown. /// protected virtual void OnDropDownShow(EventArgs e) { EventHandler handler = (EventHandler)Events[EventDropDownShow]; if (handler != null) { handler(this, e); } } ////// /// called when the default item is clicked /// protected internal virtual void OnDropDownOpened(System.EventArgs e) { // only send the event if we're the thing that currently owns the DropDown. if (DropDown.OwnerItem == this) { EventHandler handler = (EventHandler)Events[EventDropDownOpened]; if (handler != null) handler(this, e); } } ////// /// called when the default item is clicked /// protected internal virtual void OnDropDownClosed(System.EventArgs e) { // only send the event if we're the thing that currently owns the DropDown. this.Invalidate(); if (DropDown.OwnerItem == this) { EventHandler handler = (EventHandler)Events[EventDropDownClosed]; if (handler != null) handler(this, e); if (!DropDown.IsAutoGenerated) { DropDown.OwnerItem = null; } } } ////// /// called when the default item is clicked /// protected internal virtual void OnDropDownItemClicked(ToolStripItemClickedEventArgs e) { // only send the event if we're the thing that currently owns the DropDown. if (DropDown.OwnerItem == this) { ToolStripItemClickedEventHandler handler = (ToolStripItemClickedEventHandler)Events[EventDropDownItemClicked]; if (handler != null) handler(this, e); } } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] protected internal override bool ProcessCmdKey(ref Message m, Keys keyData) { if (HasDropDownItems) { return DropDown.ProcessCmdKeyInternal(ref m, keyData); } return base.ProcessCmdKey(ref m, keyData); } ///[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected internal override bool ProcessDialogKey(Keys keyData) { Keys keyCode = (Keys)keyData & Keys.KeyCode; if (HasDropDownItems) { // VSWhidbey 478068: items on the overflow should have the same kind of keyboard handling as a toplevel bool isToplevel = (!IsOnDropDown || IsOnOverflow); if (isToplevel && (keyCode == Keys.Down || keyCode == Keys.Up || keyCode == Keys.Enter || (SupportsSpaceKey && keyCode == Keys.Space))) { Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] open submenu from toplevel item"); if (Enabled || DesignMode) { // |__[ * File ]_____| * is where you are. Up or down arrow hit should expand menu this.ShowDropDown(); this.DropDown.SelectNextToolStripItem(null, true); }// else eat the key return true; } else if (!isToplevel) { // if we're on a DropDown - then cascade out. bool menusCascadeRight = (((int)DropDownDirection & 0x0001) == 0); bool forward = ((keyCode == Keys.Enter) || (SupportsSpaceKey && keyCode == Keys.Space)); forward = (forward || (menusCascadeRight && keyCode == Keys.Left) || (!menusCascadeRight && keyCode == Keys.Right)); if (forward) { Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] open submenu from NON-toplevel item"); if (Enabled || DesignMode) { this.ShowDropDown(); this.DropDown.SelectNextToolStripItem(null, true); } // else eat the key return true; } } } if (IsOnDropDown) { bool menusCascadeRight = (((int)DropDownDirection & 0x0001) == 0); bool backward = ((menusCascadeRight && keyCode == Keys.Right) || (!menusCascadeRight && keyCode == Keys.Left)); if (backward) { Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] close submenu from NON-toplevel item"); // we're on a drop down but we're heading back up the chain. // remember to select the item that displayed this dropdown. ToolStripDropDown parent = GetCurrentParentDropDown(); if (parent != null && !parent.IsFirstDropDown) { // we're walking back up the dropdown chain. parent.SelectPreviousToolStrip(); return true; } // else if (parent.IsFirstDropDown) // the base handling (ToolStripDropDown.ProcessArrowKey) will perform auto-expansion of // the previous item in the menu. } } Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] ddi calling base"); return base.ProcessDialogKey(keyData); } private ToolStripDropDownDirection RTLTranslateDropDownDirection(ToolStripDropDownDirection dropDownDirection, RightToLeft rightToLeft) { switch (dropDownDirection) { case ToolStripDropDownDirection.AboveLeft: return ToolStripDropDownDirection.AboveRight; case ToolStripDropDownDirection.AboveRight: return ToolStripDropDownDirection.AboveLeft; case ToolStripDropDownDirection.BelowRight: return ToolStripDropDownDirection.BelowLeft; case ToolStripDropDownDirection.BelowLeft: return ToolStripDropDownDirection.BelowRight; case ToolStripDropDownDirection.Right: return ToolStripDropDownDirection.Left; case ToolStripDropDownDirection.Left: return ToolStripDropDownDirection.Right; } Debug.Fail("Why are we here"); // dont expect it to come to this but just in case here are the real defaults. if (IsOnDropDown) { return (rightToLeft == RightToLeft.Yes) ? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right; } else { return (rightToLeft == RightToLeft.Yes) ? ToolStripDropDownDirection.BelowLeft : ToolStripDropDownDirection.BelowRight; } } /// /// /// Shows the DropDown, if one is set. /// public void ShowDropDown() { this.ShowDropDown(false); } internal void ShowDropDown(bool mousePush) { this.ShowDropDownInternal(); ToolStripDropDownMenu menu = this.dropDown as ToolStripDropDownMenu; if (menu != null) { if (!mousePush) { menu.ResetScrollPosition(); } menu.RestoreScrollPosition(); } } private void ShowDropDownInternal() { if (this.dropDown == null || (!this.dropDown.Visible)) { // VSWhidbey 469145 we want to show if there's no dropdown // or if the dropdown is not visible. OnDropDownShow(EventArgs.Empty); } // the act of setting the drop down visible the first time sets the parent // it seems that GetVisibleCore returns true if your parent is null. if (this.dropDown != null && !this.dropDown.Visible) { if (this.dropDown.IsAutoGenerated && this.DropDownItems.Count <= 0) { return; // this is a no-op for autogenerated drop downs. } if (this.DropDown == this.ParentInternal) { throw new InvalidOperationException(SR.GetString(SR.ToolStripShowDropDownInvalidOperation)); } this.dropDown.OwnerItem = this; this.dropDown.Location = DropDownLocation; this.dropDown.Show(); this.Invalidate(); } } private bool ShouldSerializeDropDown() { return dropDown != null && !dropDown.IsAutoGenerated; } private bool ShouldSerializeDropDownDirection() { return (toolStripDropDownDirection != ToolStripDropDownDirection.Default); } private bool ShouldSerializeDropDownItems() { return (dropDown != null && dropDown.IsAutoGenerated); } } ///public class ToolStripDropDownItemAccessibleObject : ToolStripItem.ToolStripItemAccessibleObject { private ToolStripDropDownItem owner; /// public ToolStripDropDownItemAccessibleObject(ToolStripDropDownItem item) : base(item) { owner = item; } /// public override AccessibleRole Role { get { AccessibleRole role = Owner.AccessibleRole; if (role != AccessibleRole.Default) { return role; } return AccessibleRole.MenuItem; } } /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void DoDefaultAction() { ToolStripDropDownItem item = Owner as ToolStripDropDownItem; if (item != null && item.HasDropDownItems) { item.ShowDropDown(); } else { base.DoDefaultAction(); } } public override AccessibleObject GetChild(int index) { if ((owner == null) || !owner.HasDropDownItems) { return null; } return owner.DropDown.AccessibilityObject.GetChild(index); } public override int GetChildCount() { if ((owner == null) || !owner.HasDropDownItems) { return -1; } if (owner.DropDown.LayoutRequired) { LayoutTransaction.DoLayout(owner.DropDown, owner.DropDown, PropertyNames.Items); } return owner.DropDown.AccessibilityObject.GetChildCount(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System; using System.Drawing; using System.Windows.Forms; using System.ComponentModel; using System.Diagnostics; using System.Security.Permissions; using System.Windows.Forms.Layout; ////// /// Base class for ToolStripItems that display DropDown windows. /// [Designer("System.Windows.Forms.Design.ToolStripMenuItemDesigner, " + AssemblyRef.SystemDesign)] [DefaultProperty("DropDownItems")] public abstract class ToolStripDropDownItem : ToolStripItem { private ToolStripDropDown dropDown = null; private ToolStripDropDownDirection toolStripDropDownDirection = ToolStripDropDownDirection.Default; private static readonly object EventDropDownShow = new object(); private static readonly object EventDropDownHide = new object(); private static readonly object EventDropDownOpened = new object(); private static readonly object EventDropDownClosed = new object(); private static readonly object EventDropDownItemClicked = new object(); ////// /// Protected ctor so you can't create one of these without deriving from it. /// protected ToolStripDropDownItem() { } protected ToolStripDropDownItem(string text, Image image, EventHandler onClick) : base(text, image, onClick) { } protected ToolStripDropDownItem(string text, Image image, EventHandler onClick, string name) : base(text, image, onClick, name) { } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] protected ToolStripDropDownItem(string text, Image image, params ToolStripItem[] dropDownItems) : this(text, image, (EventHandler)null) { if (dropDownItems != null) { this.DropDownItems.AddRange(dropDownItems); } } ////// /// The ToolStripDropDown that will be displayed when this item is clicked. /// [ TypeConverter(typeof(ReferenceConverter)), SRCategory(SR.CatData), SRDescription(SR.ToolStripDropDownDescr) ] public ToolStripDropDown DropDown { get { if (dropDown == null) { DropDown = CreateDefaultDropDown(); if (!(this is ToolStripOverflowButton)) { dropDown.SetAutoGeneratedInternal(true); } } return dropDown; } set { if (dropDown != value) { if (dropDown != null) { dropDown.Opened -= new EventHandler(DropDown_Opened); dropDown.Closed -= new ToolStripDropDownClosedEventHandler(DropDown_Closed); dropDown.ItemClicked -= new ToolStripItemClickedEventHandler(DropDown_ItemClicked); dropDown.UnassignDropDownItem(); } dropDown = value; if (dropDown != null) { dropDown.Opened += new EventHandler(DropDown_Opened); dropDown.Closed += new ToolStripDropDownClosedEventHandler(DropDown_Closed); dropDown.ItemClicked += new ToolStripItemClickedEventHandler(DropDown_ItemClicked); dropDown.AssignToDropDownItem(); } } } } // the area which activates the dropdown. internal virtual Rectangle DropDownButtonArea { get { return this.Bounds; } } [Browsable(false)] [SRDescription(SR.ToolStripDropDownItemDropDownDirectionDescr)] [SRCategory(SR.CatBehavior)] public ToolStripDropDownDirection DropDownDirection { get { if (toolStripDropDownDirection == ToolStripDropDownDirection.Default) { ToolStrip parent = ParentInternal; if (parent != null) { ToolStripDropDownDirection dropDownDirection = parent.DefaultDropDownDirection; if (OppositeDropDownAlign || this.RightToLeft != parent.RightToLeft && (this.RightToLeft != RightToLeft.Inherit)) { dropDownDirection = RTLTranslateDropDownDirection(dropDownDirection, RightToLeft); } if (IsOnDropDown) { // we gotta make sure that we dont collide with the existing menu. Rectangle bounds = GetDropDownBounds(dropDownDirection); Rectangle ownerItemBounds = new Rectangle(TranslatePoint(Point.Empty, ToolStripPointType.ToolStripItemCoords, ToolStripPointType.ScreenCoords), Size); Rectangle intersectionBetweenChildAndParent = Rectangle.Intersect(bounds, ownerItemBounds); // grab the intersection if (intersectionBetweenChildAndParent.Width >= 2) { RightToLeft toggledRightToLeft = (RightToLeft == RightToLeft.Yes) ? RightToLeft.No : RightToLeft.Yes; ToolStripDropDownDirection newDropDownDirection = RTLTranslateDropDownDirection(dropDownDirection, toggledRightToLeft); // verify that changing the dropdown direction actually causes less intersection. int newIntersectionWidth = Rectangle.Intersect(GetDropDownBounds(newDropDownDirection), ownerItemBounds).Width; if (newIntersectionWidth < intersectionBetweenChildAndParent.Width) { dropDownDirection = newDropDownDirection; } } } return dropDownDirection; } } // someone has set a custom override return toolStripDropDownDirection; } set { // cant use Enum.IsValid as its not sequential switch (value) { case ToolStripDropDownDirection.AboveLeft: case ToolStripDropDownDirection.AboveRight: case ToolStripDropDownDirection.BelowLeft: case ToolStripDropDownDirection.BelowRight: case ToolStripDropDownDirection.Left: case ToolStripDropDownDirection.Right: case ToolStripDropDownDirection.Default: break; default: throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolStripDropDownDirection)); } if (toolStripDropDownDirection != value) { toolStripDropDownDirection = value; if (HasDropDownItems && DropDown.Visible) { DropDown.Location = DropDownLocation; } } } } ////// /// Occurs when the dropdown is closed /// [ SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownClosedDecr) ] public event EventHandler DropDownClosed { add { Events.AddHandler(EventDropDownClosed, value); } remove { Events.RemoveHandler(EventDropDownClosed, value); } } ///internal protected virtual Point DropDownLocation { get { if (ParentInternal == null || !HasDropDownItems){ return Point.Empty; } ToolStripDropDownDirection dropDownDirection = DropDownDirection; return GetDropDownBounds(dropDownDirection).Location; } } /// [ SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpeningDescr) ] public event EventHandler DropDownOpening { add { Events.AddHandler(EventDropDownShow, value); } remove { Events.RemoveHandler(EventDropDownShow, value); } } /// /// /// Occurs when the dropdown is opened /// [ SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpenedDescr) ] public event EventHandler DropDownOpened { add { Events.AddHandler(EventDropDownOpened, value); } remove { Events.RemoveHandler(EventDropDownOpened, value); } } ////// /// Returns the DropDown's items collection. /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Content), SRCategory(SR.CatData), SRDescription(SR.ToolStripDropDownItemsDescr) ] public ToolStripItemCollection DropDownItems { get { return DropDown.Items; } } ////// /// Occurs when the dropdown is opened /// [SRCategory(SR.CatAction)] public event ToolStripItemClickedEventHandler DropDownItemClicked { add { Events.AddHandler(EventDropDownItemClicked, value); } remove { Events.RemoveHandler(EventDropDownItemClicked, value); } } ///[Browsable(false)] public virtual bool HasDropDownItems { get { //VSWhidbey 354665: use count of visible DisplayedItems instead so that we take into account things that arent visible return (dropDown != null) && dropDown.HasVisibleItems; } } internal bool HasDropDown { get { return dropDown != null; } } /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override bool Pressed { get { // if (dropDown != null) { if (DropDown.AutoClose || !IsInDesignMode || (IsInDesignMode && !IsOnDropDown)){ return DropDown.OwnerItem == this && DropDown.Visible; } } return base.Pressed; } } internal virtual bool OppositeDropDownAlign { get { return false; } } internal virtual void AutoHide(ToolStripItem otherItemBeingSelected) { HideDropDown(); } /// protected override AccessibleObject CreateAccessibilityInstance() { return new ToolStripDropDownItemAccessibleObject(this); } /// protected virtual ToolStripDropDown CreateDefaultDropDown() { // AutoGenerate a Winbar DropDown - set the property so we hook events return new ToolStripDropDown(this, true); } private Rectangle DropDownDirectionToDropDownBounds(ToolStripDropDownDirection dropDownDirection, Rectangle dropDownBounds) { Point offset = Point.Empty; switch (dropDownDirection) { case ToolStripDropDownDirection.AboveLeft: offset.X = - dropDownBounds.Width + this.Width; offset.Y = - dropDownBounds.Height+1; break; case ToolStripDropDownDirection.AboveRight: offset.Y = - dropDownBounds.Height+1; break; case ToolStripDropDownDirection.BelowRight: offset.Y = this.Height-1; break; case ToolStripDropDownDirection.BelowLeft: offset.X = - dropDownBounds.Width + this.Width; offset.Y = this.Height-1; break; case ToolStripDropDownDirection.Right: offset.X = this.Width; if (!IsOnDropDown) { // overlap the toplevel toolstrip offset.X -=1; } break; case ToolStripDropDownDirection.Left: offset.X = - dropDownBounds.Width; break; } Point itemScreenLocation = this.TranslatePoint(Point.Empty, ToolStripPointType.ToolStripItemCoords, ToolStripPointType.ScreenCoords); dropDownBounds.Location = new Point(itemScreenLocation.X + offset.X, itemScreenLocation.Y + offset.Y); dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(dropDownBounds); return dropDownBounds; } private void DropDown_Closed(object sender, ToolStripDropDownClosedEventArgs e) { OnDropDownClosed(EventArgs.Empty); } private void DropDown_Opened(object sender, EventArgs e) { OnDropDownOpened(EventArgs.Empty); } private void DropDown_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { OnDropDownItemClicked(e); } /// /// /// Make sure we unhook dropdown events. /// protected override void Dispose(bool disposing) { if (this.dropDown != null) { dropDown.Opened -= new EventHandler(DropDown_Opened); dropDown.Closed -= new ToolStripDropDownClosedEventHandler(DropDown_Closed); dropDown.ItemClicked -= new ToolStripItemClickedEventHandler(DropDown_ItemClicked); if (disposing && dropDown.IsAutoGenerated) { // if we created the dropdown, dispose it and its children. dropDown.Dispose(); dropDown = null; } } base.Dispose(disposing); } private Rectangle GetDropDownBounds(ToolStripDropDownDirection dropDownDirection) { Rectangle dropDownBounds = new Rectangle(Point.Empty, DropDown.GetSuggestedSize()); // calculate the offset from the upper left hand corner of the item. dropDownBounds = DropDownDirectionToDropDownBounds(dropDownDirection, dropDownBounds); // we should make sure we dont obscure the owner item. Rectangle itemScreenBounds = new Rectangle(this.TranslatePoint(Point.Empty, ToolStripPointType.ToolStripItemCoords, ToolStripPointType.ScreenCoords), this.Size); if (Rectangle.Intersect(dropDownBounds, itemScreenBounds).Height > 1) { bool rtl = (RightToLeft == RightToLeft.Yes); // try positioning to the left if (Rectangle.Intersect(dropDownBounds, itemScreenBounds).Width > 1) { dropDownBounds = DropDownDirectionToDropDownBounds(!rtl ? ToolStripDropDownDirection.Right : ToolStripDropDownDirection.Left, dropDownBounds); } // try positioning to the right if (Rectangle.Intersect(dropDownBounds, itemScreenBounds).Width > 1) { dropDownBounds = DropDownDirectionToDropDownBounds(!rtl ? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right, dropDownBounds); } } return dropDownBounds; } ////// /// Hides the DropDown, if it is visible. /// public void HideDropDown() { // consider - CloseEventArgs to prevent shutting down. OnDropDownHide(EventArgs.Empty); if (this.dropDown != null && this.dropDown.Visible) { DropDown.Visible = false; } } protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); if (dropDown != null) { dropDown.OnOwnerItemFontChanged(EventArgs.Empty); } } ///protected override void OnBoundsChanged() { base.OnBoundsChanged(); //Reset the Bounds... if (this.dropDown != null && this.dropDown.Visible) { this.dropDown.Bounds = GetDropDownBounds(DropDownDirection); } } protected override void OnRightToLeftChanged(EventArgs e) { base.OnRightToLeftChanged(e); if (HasDropDownItems) { // only perform a layout on a visible dropdown - otherwise clear the preferred size cache. if (DropDown.Visible) { LayoutTransaction.DoLayout(DropDown, this, PropertyNames.RightToLeft); } else { CommonProperties.xClearPreferredSizeCache(DropDown); DropDown.LayoutRequired = true; } } } internal override void OnImageScalingSizeChanged(EventArgs e) { base.OnImageScalingSizeChanged(e); if (HasDropDown && DropDown.IsAutoGenerated) { DropDown.DoLayoutIfHandleCreated(new ToolStripItemEventArgs(this)); } } /// /// /// Called as a response to HideDropDown /// protected virtual void OnDropDownHide(EventArgs e) { this.Invalidate(); EventHandler handler = (EventHandler)Events[EventDropDownHide]; if (handler != null) handler(this, e); } ////// /// Last chance to stick in the DropDown before it is shown. /// protected virtual void OnDropDownShow(EventArgs e) { EventHandler handler = (EventHandler)Events[EventDropDownShow]; if (handler != null) { handler(this, e); } } ////// /// called when the default item is clicked /// protected internal virtual void OnDropDownOpened(System.EventArgs e) { // only send the event if we're the thing that currently owns the DropDown. if (DropDown.OwnerItem == this) { EventHandler handler = (EventHandler)Events[EventDropDownOpened]; if (handler != null) handler(this, e); } } ////// /// called when the default item is clicked /// protected internal virtual void OnDropDownClosed(System.EventArgs e) { // only send the event if we're the thing that currently owns the DropDown. this.Invalidate(); if (DropDown.OwnerItem == this) { EventHandler handler = (EventHandler)Events[EventDropDownClosed]; if (handler != null) handler(this, e); if (!DropDown.IsAutoGenerated) { DropDown.OwnerItem = null; } } } ////// /// called when the default item is clicked /// protected internal virtual void OnDropDownItemClicked(ToolStripItemClickedEventArgs e) { // only send the event if we're the thing that currently owns the DropDown. if (DropDown.OwnerItem == this) { ToolStripItemClickedEventHandler handler = (ToolStripItemClickedEventHandler)Events[EventDropDownItemClicked]; if (handler != null) handler(this, e); } } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] protected internal override bool ProcessCmdKey(ref Message m, Keys keyData) { if (HasDropDownItems) { return DropDown.ProcessCmdKeyInternal(ref m, keyData); } return base.ProcessCmdKey(ref m, keyData); } ///[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected internal override bool ProcessDialogKey(Keys keyData) { Keys keyCode = (Keys)keyData & Keys.KeyCode; if (HasDropDownItems) { // VSWhidbey 478068: items on the overflow should have the same kind of keyboard handling as a toplevel bool isToplevel = (!IsOnDropDown || IsOnOverflow); if (isToplevel && (keyCode == Keys.Down || keyCode == Keys.Up || keyCode == Keys.Enter || (SupportsSpaceKey && keyCode == Keys.Space))) { Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] open submenu from toplevel item"); if (Enabled || DesignMode) { // |__[ * File ]_____| * is where you are. Up or down arrow hit should expand menu this.ShowDropDown(); this.DropDown.SelectNextToolStripItem(null, true); }// else eat the key return true; } else if (!isToplevel) { // if we're on a DropDown - then cascade out. bool menusCascadeRight = (((int)DropDownDirection & 0x0001) == 0); bool forward = ((keyCode == Keys.Enter) || (SupportsSpaceKey && keyCode == Keys.Space)); forward = (forward || (menusCascadeRight && keyCode == Keys.Left) || (!menusCascadeRight && keyCode == Keys.Right)); if (forward) { Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] open submenu from NON-toplevel item"); if (Enabled || DesignMode) { this.ShowDropDown(); this.DropDown.SelectNextToolStripItem(null, true); } // else eat the key return true; } } } if (IsOnDropDown) { bool menusCascadeRight = (((int)DropDownDirection & 0x0001) == 0); bool backward = ((menusCascadeRight && keyCode == Keys.Right) || (!menusCascadeRight && keyCode == Keys.Left)); if (backward) { Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] close submenu from NON-toplevel item"); // we're on a drop down but we're heading back up the chain. // remember to select the item that displayed this dropdown. ToolStripDropDown parent = GetCurrentParentDropDown(); if (parent != null && !parent.IsFirstDropDown) { // we're walking back up the dropdown chain. parent.SelectPreviousToolStrip(); return true; } // else if (parent.IsFirstDropDown) // the base handling (ToolStripDropDown.ProcessArrowKey) will perform auto-expansion of // the previous item in the menu. } } Debug.WriteLineIf(ToolStrip.SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] ddi calling base"); return base.ProcessDialogKey(keyData); } private ToolStripDropDownDirection RTLTranslateDropDownDirection(ToolStripDropDownDirection dropDownDirection, RightToLeft rightToLeft) { switch (dropDownDirection) { case ToolStripDropDownDirection.AboveLeft: return ToolStripDropDownDirection.AboveRight; case ToolStripDropDownDirection.AboveRight: return ToolStripDropDownDirection.AboveLeft; case ToolStripDropDownDirection.BelowRight: return ToolStripDropDownDirection.BelowLeft; case ToolStripDropDownDirection.BelowLeft: return ToolStripDropDownDirection.BelowRight; case ToolStripDropDownDirection.Right: return ToolStripDropDownDirection.Left; case ToolStripDropDownDirection.Left: return ToolStripDropDownDirection.Right; } Debug.Fail("Why are we here"); // dont expect it to come to this but just in case here are the real defaults. if (IsOnDropDown) { return (rightToLeft == RightToLeft.Yes) ? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right; } else { return (rightToLeft == RightToLeft.Yes) ? ToolStripDropDownDirection.BelowLeft : ToolStripDropDownDirection.BelowRight; } } /// /// /// Shows the DropDown, if one is set. /// public void ShowDropDown() { this.ShowDropDown(false); } internal void ShowDropDown(bool mousePush) { this.ShowDropDownInternal(); ToolStripDropDownMenu menu = this.dropDown as ToolStripDropDownMenu; if (menu != null) { if (!mousePush) { menu.ResetScrollPosition(); } menu.RestoreScrollPosition(); } } private void ShowDropDownInternal() { if (this.dropDown == null || (!this.dropDown.Visible)) { // VSWhidbey 469145 we want to show if there's no dropdown // or if the dropdown is not visible. OnDropDownShow(EventArgs.Empty); } // the act of setting the drop down visible the first time sets the parent // it seems that GetVisibleCore returns true if your parent is null. if (this.dropDown != null && !this.dropDown.Visible) { if (this.dropDown.IsAutoGenerated && this.DropDownItems.Count <= 0) { return; // this is a no-op for autogenerated drop downs. } if (this.DropDown == this.ParentInternal) { throw new InvalidOperationException(SR.GetString(SR.ToolStripShowDropDownInvalidOperation)); } this.dropDown.OwnerItem = this; this.dropDown.Location = DropDownLocation; this.dropDown.Show(); this.Invalidate(); } } private bool ShouldSerializeDropDown() { return dropDown != null && !dropDown.IsAutoGenerated; } private bool ShouldSerializeDropDownDirection() { return (toolStripDropDownDirection != ToolStripDropDownDirection.Default); } private bool ShouldSerializeDropDownItems() { return (dropDown != null && dropDown.IsAutoGenerated); } } ///public class ToolStripDropDownItemAccessibleObject : ToolStripItem.ToolStripItemAccessibleObject { private ToolStripDropDownItem owner; /// public ToolStripDropDownItemAccessibleObject(ToolStripDropDownItem item) : base(item) { owner = item; } /// public override AccessibleRole Role { get { AccessibleRole role = Owner.AccessibleRole; if (role != AccessibleRole.Default) { return role; } return AccessibleRole.MenuItem; } } /// [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void DoDefaultAction() { ToolStripDropDownItem item = Owner as ToolStripDropDownItem; if (item != null && item.HasDropDownItems) { item.ShowDropDown(); } else { base.DoDefaultAction(); } } public override AccessibleObject GetChild(int index) { if ((owner == null) || !owner.HasDropDownItems) { return null; } return owner.DropDown.AccessibilityObject.GetChild(index); } public override int GetChildCount() { if ((owner == null) || !owner.HasDropDownItems) { return -1; } if (owner.DropDown.LayoutRequired) { LayoutTransaction.DoLayout(owner.DropDown, owner.DropDown, PropertyNames.Items); } return owner.DropDown.AccessibilityObject.GetChildCount(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WmlCommandAdapter.cs
- CallbackValidator.cs
- UnsettableComboBox.cs
- DNS.cs
- sitestring.cs
- ServiceAuthorizationElement.cs
- ViewBase.cs
- FactoryMaker.cs
- safelink.cs
- BevelBitmapEffect.cs
- NotCondition.cs
- ExpressionDumper.cs
- XsltInput.cs
- SpellerHighlightLayer.cs
- ProfilePropertyNameValidator.cs
- DataServiceHostFactory.cs
- TransformerConfigurationWizardBase.cs
- PrintController.cs
- ParenthesizePropertyNameAttribute.cs
- HttpSysSettings.cs
- WindowsScrollBar.cs
- ReadOnlyKeyedCollection.cs
- _ShellExpression.cs
- AuthenticationModulesSection.cs
- QueryContinueDragEventArgs.cs
- ObjectDataSourceStatusEventArgs.cs
- DecoderNLS.cs
- CodeSnippetStatement.cs
- MailHeaderInfo.cs
- TypeResolvingOptions.cs
- UIElement.cs
- ApplicationDirectory.cs
- Logging.cs
- NavigatorInput.cs
- SafeHandle.cs
- SqlInternalConnectionTds.cs
- EntityModelSchemaGenerator.cs
- NotImplementedException.cs
- StringStorage.cs
- LabelLiteral.cs
- ShapeTypeface.cs
- SoapObjectWriter.cs
- PropertyPath.cs
- WebServicesInteroperability.cs
- CheckBoxPopupAdapter.cs
- StreamWriter.cs
- MSAAWinEventWrap.cs
- GeneralTransformCollection.cs
- DiscreteKeyFrames.cs
- BindMarkupExtensionSerializer.cs
- TextEndOfLine.cs
- TypeUtils.cs
- DbXmlEnabledProviderManifest.cs
- LineGeometry.cs
- XmlCodeExporter.cs
- AddInAdapter.cs
- _ConnectOverlappedAsyncResult.cs
- Baml6ConstructorInfo.cs
- GridEntryCollection.cs
- Decoder.cs
- PropertyInformation.cs
- ColorDialog.cs
- SafeFileMapViewHandle.cs
- MobileControlsSection.cs
- SoapSchemaImporter.cs
- PriorityItem.cs
- FormatStringEditor.cs
- FileUtil.cs
- UserControlCodeDomTreeGenerator.cs
- RSAOAEPKeyExchangeDeformatter.cs
- LockedBorderGlyph.cs
- RecommendedAsConfigurableAttribute.cs
- ProfileSettingsCollection.cs
- LinkLabelLinkClickedEvent.cs
- SignedInfo.cs
- WebUtility.cs
- PtsHost.cs
- MailAddressCollection.cs
- UrlPropertyAttribute.cs
- PriorityBindingExpression.cs
- CodeSnippetExpression.cs
- StateChangeEvent.cs
- SamlConditions.cs
- TransformConverter.cs
- WindowsUserNameSecurityTokenAuthenticator.cs
- WSSecurityXXX2005.cs
- DrawListViewItemEventArgs.cs
- SymDocumentType.cs
- InfoCardRSAOAEPKeyExchangeFormatter.cs
- ErrorWebPart.cs
- TimelineGroup.cs
- ObjectAnimationBase.cs
- SoapAttributeOverrides.cs
- RoleServiceManager.cs
- Baml2006SchemaContext.cs
- Speller.cs
- FilePrompt.cs
- ServiceOperationListItemList.cs
- FixedSOMPageConstructor.cs
- WindowsScroll.cs