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;
77 this.drop_down = value;
78 this.drop_down.OwnerItem = this;
83 public ToolStripDropDownDirection DropDownDirection {
84 get { return this.drop_down_direction; }
86 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
87 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
89 this.drop_down_direction = value;
93 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
94 public ToolStripItemCollection DropDownItems {
95 get { return this.DropDown.Items; }
99 public virtual bool HasDropDownItems {
100 get { return this.drop_down != null && this.DropDown.Items.Count != 0; }
104 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
105 public override bool Pressed {
106 get { return base.Pressed || (this.drop_down != null && this.DropDown.Visible); }
110 #region Protected Properties
111 protected internal virtual Point DropDownLocation {
115 if (this.IsOnDropDown) {
116 p = Parent.PointToScreen (new Point (this.Bounds.Left, this.Bounds.Top - 1));
117 p.X += this.Bounds.Width;
118 p.Y += this.Bounds.Left;
122 p = new Point (this.Bounds.Left, this.Bounds.Bottom - 1);
124 return Parent.PointToScreen (p);
129 #region Public Methods
130 public void HideDropDown ()
132 if (this.drop_down == null || !this.DropDown.Visible)
135 // OnDropDownHide is called before actually closing DropDown
136 this.OnDropDownHide (EventArgs.Empty);
137 this.DropDown.Close (ToolStripDropDownCloseReason.CloseCalled);
138 this.is_pressed = false;
142 public void ShowDropDown ()
144 // Don't go through this whole deal if
145 // the DropDown is already visible
146 if (this.DropDown.Visible)
149 // Call this before the HasDropDownItems check to give
150 // users a chance to handle it and add drop down items
151 this.OnDropDownShow (EventArgs.Empty);
153 if (!this.HasDropDownItems)
157 this.DropDown.Show (this.DropDownLocation);
161 #region Protected Methods
162 protected override AccessibleObject CreateAccessibilityInstance ()
164 return new ToolStripDropDownItemAccessibleObject (this);
167 protected virtual ToolStripDropDown CreateDefaultDropDown ()
169 ToolStripDropDown tsdd = new ToolStripDropDown ();
170 tsdd.OwnerItem = this;
174 protected override void Dispose (bool disposing)
177 if (this.HasDropDownItems)
178 foreach (ToolStripItem tsi in this.DropDownItems)
179 if (tsi is ToolStripMenuItem)
180 ToolStripManager.RemoveToolStripMenuItem ((ToolStripMenuItem)tsi);
182 if (drop_down != null)
183 ToolStripManager.RemoveToolStrip (drop_down);
185 base.Dispose (disposing);
189 protected override void OnBoundsChanged ()
191 base.OnBoundsChanged ();
194 protected internal virtual void OnDropDownClosed (EventArgs e)
196 EventHandler eh = (EventHandler)(Events [DropDownClosedEvent]);
201 protected virtual void OnDropDownHide (EventArgs e)
205 protected internal virtual void OnDropDownItemClicked (ToolStripItemClickedEventArgs e)
207 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [DropDownItemClickedEvent]);
212 protected internal virtual void OnDropDownOpened (EventArgs e)
214 EventHandler eh = (EventHandler)(Events [DropDownOpenedEvent]);
219 protected virtual void OnDropDownShow (EventArgs e)
221 EventHandler eh = (EventHandler)(Events[DropDownOpeningEvent]);
226 protected override void OnFontChanged (EventArgs e)
228 base.OnFontChanged (e);
230 // don't use DropDown directly, since doing that
231 // would created the DropDown control
232 if (drop_down != null)
233 drop_down.Font = Font;
236 protected override void OnRightToLeftChanged (EventArgs e)
238 base.OnRightToLeftChanged (e);
241 protected internal override bool ProcessCmdKey (ref Message m, Keys keyData)
243 if (this.HasDropDownItems)
244 foreach (ToolStripItem tsi in this.DropDownItems)
245 if (tsi.ProcessCmdKey (ref m, keyData) == true)
248 return base.ProcessCmdKey (ref m, keyData);
251 protected internal override bool ProcessDialogKey (Keys keyData)
253 if (!this.Selected || !this.HasDropDownItems)
254 return base.ProcessDialogKey (keyData);
256 if (!this.IsOnDropDown) {
257 if (this.Parent.Orientation == Orientation.Horizontal) {
258 if (keyData == Keys.Down || keyData == Keys.Enter) {
259 if (this.Parent is MenuStrip)
260 (this.Parent as MenuStrip).MenuDroppedDown = true;
261 this.ShowDropDown ();
262 this.DropDown.SelectNextToolStripItem (null, true);
266 if (keyData == Keys.Right || keyData == Keys.Enter) {
267 if (this.Parent is MenuStrip)
268 (this.Parent as MenuStrip).MenuDroppedDown = true;
269 this.ShowDropDown ();
270 this.DropDown.SelectNextToolStripItem (null, true);
275 if (keyData == Keys.Right || keyData == Keys.Enter) {
276 if (this.HasDropDownItems) {
277 this.ShowDropDown ();
278 this.DropDown.SelectNextToolStripItem (null, true);
285 return base.ProcessDialogKey (keyData);
289 #region Public Events
290 static object DropDownClosedEvent = new object ();
291 static object DropDownItemClickedEvent = new object ();
292 static object DropDownOpenedEvent = new object ();
293 static object DropDownOpeningEvent = new object ();
295 public event EventHandler DropDownClosed {
296 add { Events.AddHandler (DropDownClosedEvent, value); }
297 remove { Events.RemoveHandler (DropDownClosedEvent, value); }
300 public event ToolStripItemClickedEventHandler DropDownItemClicked {
301 add { Events.AddHandler (DropDownItemClickedEvent, value); }
302 remove { Events.RemoveHandler (DropDownItemClickedEvent, value); }
305 public event EventHandler DropDownOpened {
306 add { Events.AddHandler (DropDownOpenedEvent, value); }
307 remove { Events.RemoveHandler (DropDownOpenedEvent, value); }
310 public event EventHandler DropDownOpening {
311 add { Events.AddHandler (DropDownOpeningEvent, value); }
312 remove { Events.RemoveHandler (DropDownOpeningEvent, value); }
316 #region Internal Methods
317 internal override void Dismiss (ToolStripDropDownCloseReason reason)
319 if (this.HasDropDownItems && this.DropDown.Visible)
320 this.DropDown.Dismiss (reason);
322 base.Dismiss (reason);
325 internal override void HandleClick (int mouse_clicks, EventArgs e)
330 internal void HideDropDown (ToolStripDropDownCloseReason reason)
332 if (this.drop_down == null || !this.DropDown.Visible)
335 // OnDropDownHide is called before actually closing DropDown
336 this.OnDropDownHide (EventArgs.Empty);
337 this.DropDown.Close (reason);
338 this.is_pressed = false;
342 private void DropDown_ItemAdded (object sender, ToolStripItemEventArgs e)
344 e.Item.owner_item = this;