2 // ToolStripDropDownItem.cs
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2006 Jonathan Pobst
26 // Jonathan Pobst (monkey@jpobst.com)
32 using System.ComponentModel;
33 using System.Threading;
35 namespace System.Windows.Forms
37 [DefaultProperty ("DropDownItems")]
38 [Designer ("System.Windows.Forms.Design.ToolStripMenuItemDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
39 public abstract class ToolStripDropDownItem : ToolStripItem
41 internal ToolStripDropDown drop_down;
42 private ToolStripDropDownDirection drop_down_direction;
44 #region Protected Constructors
45 protected ToolStripDropDownItem () : this (string.Empty, null, null, string.Empty)
49 protected ToolStripDropDownItem (string text, Image image, EventHandler onClick)
50 : this (text, image, onClick, string.Empty)
54 protected ToolStripDropDownItem (string text, Image image, params ToolStripItem[] dropDownItems)
55 : this (text, image, null, string.Empty)
59 protected ToolStripDropDownItem (string text, Image image, EventHandler onClick, string name)
60 : base (text, image, onClick, name)
65 #region Public Properties
66 [TypeConverter (typeof (ReferenceConverter))]
67 public ToolStripDropDown DropDown {
69 if (this.drop_down == null) {
70 this.drop_down = CreateDefaultDropDown ();
71 this.drop_down.ItemAdded += new ToolStripItemEventHandler (DropDown_ItemAdded);
74 return this.drop_down;
76 set { this.drop_down = value; }
80 public ToolStripDropDownDirection DropDownDirection {
81 get { return this.drop_down_direction; }
83 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
84 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
86 this.drop_down_direction = value;
90 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
91 public ToolStripItemCollection DropDownItems {
92 get { return this.DropDown.Items; }
96 public virtual bool HasDropDownItems {
97 get { return this.drop_down != null && this.DropDown.Items.Count != 0; }
101 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
102 public override bool Pressed {
103 get { return base.Pressed || (this.drop_down != null && this.DropDown.Visible); }
107 #region Protected Properties
108 protected internal virtual Point DropDownLocation {
112 if (this.IsOnDropDown) {
113 p = Parent.PointToScreen (new Point (this.Bounds.Left, this.Bounds.Top - 1));
114 p.X += this.Bounds.Width;
115 p.Y += this.Bounds.Left;
119 p = new Point (this.Bounds.Left, this.Bounds.Bottom - 1);
121 return Parent.PointToScreen (p);
126 #region Public Methods
127 public void HideDropDown ()
129 if (this.drop_down == null || !this.DropDown.Visible)
132 this.DropDown.Close (ToolStripDropDownCloseReason.CloseCalled);
133 this.is_pressed = false;
135 this.OnDropDownHide (EventArgs.Empty);
136 this.OnDropDownClosed (EventArgs.Empty);
139 public void ShowDropDown ()
141 if (!this.HasDropDownItems)
145 this.OnDropDownOpening (this, EventArgs.Empty);
146 this.DropDown.Show (this.DropDownLocation);
147 this.OnDropDownShow (EventArgs.Empty);
148 this.OnDropDownOpened (EventArgs.Empty);
152 #region Protected Methods
153 protected override AccessibleObject CreateAccessibilityInstance ()
155 return new ToolStripDropDownItemAccessibleObject (this);
158 protected virtual ToolStripDropDown CreateDefaultDropDown ()
160 ToolStripDropDown tsdd = new ToolStripDropDown ();
161 tsdd.OwnerItem = this;
165 protected override void Dispose (bool disposing)
168 if (this.HasDropDownItems)
169 foreach (ToolStripItem tsi in this.DropDownItems)
170 if (tsi is ToolStripMenuItem)
171 ToolStripManager.RemoveToolStripMenuItem ((ToolStripMenuItem)tsi);
173 base.Dispose (disposing);
177 protected override void OnBoundsChanged ()
179 base.OnBoundsChanged ();
182 protected internal virtual void OnDropDownClosed (EventArgs e)
184 EventHandler eh = (EventHandler)(Events [DropDownClosedEvent]);
189 protected virtual void OnDropDownHide (EventArgs e)
193 protected internal virtual void OnDropDownItemClicked (ToolStripItemClickedEventArgs e)
195 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [DropDownClosedEvent]);
200 protected internal virtual void OnDropDownOpened (EventArgs e)
202 EventHandler eh = (EventHandler)(Events [DropDownOpenedEvent]);
207 protected virtual void OnDropDownShow (EventArgs e)
211 protected override void OnFontChanged (EventArgs e)
213 base.OnFontChanged (e);
216 protected override void OnRightToLeftChanged (EventArgs e)
218 base.OnRightToLeftChanged (e);
221 protected internal override bool ProcessCmdKey (ref Message m, Keys keyData)
223 if (this.HasDropDownItems)
224 foreach (ToolStripItem tsi in this.DropDownItems)
225 if (tsi.ProcessCmdKey (ref m, keyData) == true)
228 return base.ProcessCmdKey (ref m, keyData);
231 protected internal override bool ProcessDialogKey (Keys keyData)
233 if (!this.Selected || !this.HasDropDownItems)
234 return base.ProcessDialogKey (keyData);
236 if (!this.IsOnDropDown) {
237 if (this.Parent.Orientation == Orientation.Horizontal) {
238 if (keyData == Keys.Down || keyData == Keys.Enter) {
239 if (this.Parent is MenuStrip)
240 (this.Parent as MenuStrip).MenuDroppedDown = true;
241 this.ShowDropDown ();
242 this.DropDown.SelectNextToolStripItem (null, true);
246 if (keyData == Keys.Right || keyData == Keys.Enter) {
247 if (this.Parent is MenuStrip)
248 (this.Parent as MenuStrip).MenuDroppedDown = true;
249 this.ShowDropDown ();
250 this.DropDown.SelectNextToolStripItem (null, true);
255 if (keyData == Keys.Right || keyData == Keys.Enter) {
256 if (this.HasDropDownItems) {
257 this.ShowDropDown ();
258 this.DropDown.SelectNextToolStripItem (null, true);
265 return base.ProcessDialogKey (keyData);
269 #region Public Events
270 static object DropDownClosedEvent = new object ();
271 static object DropDownItemClickedEvent = new object ();
272 static object DropDownOpenedEvent = new object ();
273 static object DropDownOpeningEvent = new object ();
275 public event EventHandler DropDownClosed {
276 add { Events.AddHandler (DropDownClosedEvent, value); }
277 remove { Events.RemoveHandler (DropDownClosedEvent, value); }
280 public event ToolStripItemClickedEventHandler DropDownItemClicked {
281 add { Events.AddHandler (DropDownItemClickedEvent, value); }
282 remove { Events.RemoveHandler (DropDownItemClickedEvent, value); }
285 public event EventHandler DropDownOpened {
286 add { Events.AddHandler (DropDownOpenedEvent, value); }
287 remove { Events.RemoveHandler (DropDownOpenedEvent, value); }
290 public event EventHandler DropDownOpening {
291 add { Events.AddHandler (DropDownOpeningEvent, value); }
292 remove { Events.RemoveHandler (DropDownOpeningEvent, value); }
296 #region Internal Methods
297 internal override void Dismiss (ToolStripDropDownCloseReason reason)
299 if (this.HasDropDownItems && this.DropDown.Visible)
300 this.DropDown.Dismiss (reason);
302 base.Dismiss (reason);
305 internal override void HandleClick (EventArgs e)
310 internal void HideDropDown (ToolStripDropDownCloseReason reason)
312 if (this.drop_down == null || !this.DropDown.Visible)
315 this.DropDown.Close (reason);
316 this.is_pressed = false;
318 this.OnDropDownHide (EventArgs.Empty);
319 this.OnDropDownClosed (EventArgs.Empty);
322 private void DropDown_ItemAdded (object sender, ToolStripItemEventArgs e)
324 e.Item.owner_item = this;
327 private void OnDropDownOpening (object sender, EventArgs e)
329 EventHandler eh = (EventHandler)(Events[DropDownOpeningEvent]);