2 // ToolStripMenuItem.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.Windows.Forms.Design;
34 using System.ComponentModel.Design.Serialization;
36 namespace System.Windows.Forms
38 [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.MenuStrip | ToolStripItemDesignerAvailability.ContextMenuStrip)]
39 [DesignerSerializer ("System.Windows.Forms.Design.ToolStripMenuItemCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
40 public class ToolStripMenuItem : ToolStripDropDownItem
42 private CheckState checked_state;
43 private bool check_on_click;
44 private bool close_on_mouse_release;
45 private string shortcut_display_string;
46 private Keys shortcut_keys = Keys.None;
47 private bool show_shortcut_keys = true;
48 private Form mdi_client_form;
50 #region Public Constructors
51 public ToolStripMenuItem ()
52 : this (null, null, null, string.Empty)
56 public ToolStripMenuItem (Image image)
57 : this (null, image, null, string.Empty)
61 public ToolStripMenuItem (string text)
62 : this (text, null, null, string.Empty)
66 public ToolStripMenuItem (string text, Image image)
67 : this (text, image, null, string.Empty)
71 public ToolStripMenuItem (string text, Image image, EventHandler onClick)
72 : this (text, image, onClick, string.Empty)
76 public ToolStripMenuItem (string text, Image image, params ToolStripItem[] dropDownItems)
77 : this (text, image, null, string.Empty)
79 if (dropDownItems != null)
80 foreach (ToolStripItem tsi in dropDownItems)
81 this.DropDownItems.Add (tsi);
84 public ToolStripMenuItem (string text, Image image, EventHandler onClick, Keys shortcutKeys)
85 : this (text, image, onClick, string.Empty)
89 public ToolStripMenuItem (string text, Image image, EventHandler onClick, string name)
90 : base (text, image, onClick, name)
92 base.Overflow = ToolStripItemOverflow.Never;
96 #region Public Properties
98 [DefaultValue (false)]
99 [RefreshProperties (RefreshProperties.All)]
100 public bool Checked {
102 switch (this.checked_state) {
103 case CheckState.Unchecked:
106 case CheckState.Checked:
107 case CheckState.Indeterminate:
112 if (this.checked_state != (value ? CheckState.Checked : CheckState.Unchecked)) {
113 this.checked_state = value ? CheckState.Checked : CheckState.Unchecked;
115 this.OnCheckedChanged (EventArgs.Empty);
120 [DefaultValue (false)]
121 public bool CheckOnClick {
122 get { return this.check_on_click; }
123 set { this.check_on_click = value; }
127 [DefaultValue (CheckState.Unchecked)]
128 [RefreshProperties (RefreshProperties.All)]
129 public CheckState CheckState {
130 get { return this.checked_state; }
133 if (!Enum.IsDefined (typeof (CheckState), value))
134 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for CheckState", value));
136 this.checked_state = value;
138 this.OnCheckStateChanged (EventArgs.Empty);
142 public override bool Enabled {
143 get { return base.Enabled; }
144 set { base.Enabled = value; }
148 public bool IsMdiWindowListEntry {
149 get { return this.mdi_client_form != null; }
152 [DefaultValue (ToolStripItemOverflow.Never)]
153 public new ToolStripItemOverflow Overflow {
154 get { return base.Overflow; }
155 set { base.Overflow = value; }
159 [DefaultValue (true)]
160 public bool ShowShortcutKeys {
161 get { return this.show_shortcut_keys; }
162 set { this.show_shortcut_keys = value; }
166 [DefaultValue (null)]
167 public string ShortcutKeyDisplayString {
168 get { return this.shortcut_display_string; }
169 set { this.shortcut_display_string = value; }
173 [DefaultValue (Keys.None)]
174 public Keys ShortcutKeys {
175 get { return this.shortcut_keys; }
177 if (this.shortcut_keys != value) {
178 this.shortcut_keys = value;
180 if (this.Parent != null)
181 ToolStripManager.AddToolStripMenuItem (this);
187 #region Protected Properties
188 protected internal override Padding DefaultMargin {
189 get { return new Padding (0); }
192 protected override Padding DefaultPadding {
193 get { return new Padding (4, 0, 4, 0); }
196 protected override Size DefaultSize {
197 get { return new Size (32, 19); }
201 #region Protected Methods
202 protected override ToolStripDropDown CreateDefaultDropDown ()
204 ToolStripDropDownMenu tsddm = new ToolStripDropDownMenu ();
205 tsddm.OwnerItem = this;
209 protected override void Dispose (bool disposing)
211 base.Dispose (disposing);
214 protected virtual void OnCheckedChanged (EventArgs e)
216 EventHandler eh = (EventHandler)Events [CheckedChangedEvent];
221 protected virtual void OnCheckStateChanged (EventArgs e)
223 EventHandler eh = (EventHandler)Events [CheckStateChangedEvent];
228 protected override void OnClick (EventArgs e)
233 if (this.HasDropDownItems)
236 if (this.IsOnDropDown)
237 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
239 if (this.IsMdiWindowListEntry) {
240 this.mdi_client_form.MdiParent.MdiContainer.ActivateChild (this.mdi_client_form);
244 if (this.check_on_click)
245 this.Checked = !this.Checked;
250 protected override void OnDropDownHide (EventArgs e)
252 base.OnDropDownHide (e);
255 protected override void OnDropDownShow (EventArgs e)
257 base.OnDropDownShow (e);
260 protected override void OnFontChanged (EventArgs e)
262 base.OnFontChanged (e);
265 protected override void OnMouseDown (MouseEventArgs e)
267 if (!this.IsOnDropDown && this.HasDropDownItems && this.DropDown.Visible)
268 this.close_on_mouse_release = true;
270 if (this.HasDropDownItems && Enabled)
271 if (!this.DropDown.Visible)
272 this.ShowDropDown ();
274 base.OnMouseDown (e);
277 protected override void OnMouseEnter (EventArgs e)
279 if (this.IsOnDropDown && this.HasDropDownItems && Enabled)
280 this.ShowDropDown ();
282 base.OnMouseEnter (e);
285 protected override void OnMouseLeave (EventArgs e)
287 base.OnMouseLeave (e);
290 protected override void OnMouseUp (MouseEventArgs e)
292 if (this.close_on_mouse_release) {
293 this.DropDown.Dismiss (ToolStripDropDownCloseReason.ItemClicked);
295 this.close_on_mouse_release = false;
297 if (!this.IsOnDropDown)
298 (this.Parent as MenuStrip).MenuDroppedDown = false;
301 if (!this.HasDropDownItems && Enabled)
305 protected override void OnOwnerChanged (EventArgs e)
307 base.OnOwnerChanged (e);
310 protected override void OnPaint (System.Windows.Forms.PaintEventArgs e)
314 if (this.Owner != null) {
315 Color font_color = this.Enabled ? this.ForeColor : SystemColors.GrayText;
316 Image draw_image = this.Enabled ? this.Image : ToolStripRenderer.CreateDisabledImage (this.Image);
318 this.Owner.Renderer.DrawMenuItemBackground (new System.Windows.Forms.ToolStripItemRenderEventArgs (e.Graphics, this));
320 Rectangle text_layout_rect;
321 Rectangle image_layout_rect;
323 this.CalculateTextAndImageRectangles (out text_layout_rect, out image_layout_rect);
325 if (this.IsOnDropDown) {
326 text_layout_rect = new Rectangle (35, text_layout_rect.Top, text_layout_rect.Width, text_layout_rect.Height);
327 if (image_layout_rect != Rectangle.Empty)
328 image_layout_rect = new Rectangle (new Point (4, 3), base.GetImageSize ());
331 this.Owner.Renderer.DrawItemCheck (new ToolStripItemImageRenderEventArgs (e.Graphics, this, new Rectangle (2, 1, 19, 19)));
333 if (text_layout_rect != Rectangle.Empty)
334 this.Owner.Renderer.DrawItemText (new System.Windows.Forms.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign));
336 string key_string = GetShortcutDisplayString ();
338 if (!string.IsNullOrEmpty (key_string) && !this.HasDropDownItems) {
340 Size key_string_size = TextRenderer.MeasureText (key_string, this.Font);
341 Rectangle key_string_rect = new Rectangle (this.ContentRectangle.Right - key_string_size.Width - offset, text_layout_rect.Top, key_string_size.Width, text_layout_rect.Height);
342 this.Owner.Renderer.DrawItemText (new System.Windows.Forms.ToolStripItemTextRenderEventArgs (e.Graphics, this, key_string, key_string_rect, font_color, this.Font, this.TextAlign));
345 if (image_layout_rect != Rectangle.Empty)
346 this.Owner.Renderer.DrawItemImage (new System.Windows.Forms.ToolStripItemImageRenderEventArgs (e.Graphics, this, draw_image, image_layout_rect));
348 if (this.IsOnDropDown && this.HasDropDownItems)
349 this.Owner.Renderer.DrawArrow (new ToolStripArrowRenderEventArgs (e.Graphics, this, new Rectangle (this.Bounds.Width - 17, 2, 10, 20), Color.Black, ArrowDirection.Right));
354 protected internal override bool ProcessCmdKey (ref Message m, Keys keyData)
356 if (this.Enabled && keyData == this.shortcut_keys) {
357 this.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click);
361 return base.ProcessCmdKey (ref m, keyData);
364 protected internal override bool ProcessMnemonic (char charCode)
367 this.Parent.ChangeSelection (this);
369 if (this.HasDropDownItems) {
370 this.ShowDropDown ();
371 this.DropDown.SelectNextToolStripItem (null, true);
373 this.PerformClick ();
378 protected internal override void SetBounds (Rectangle bounds)
380 base.SetBounds (bounds);
384 #region Public Events
385 static object CheckedChangedEvent = new object ();
386 static object CheckStateChangedEvent = new object ();
388 public event EventHandler CheckedChanged {
389 add { Events.AddHandler (CheckedChangedEvent, value); }
390 remove {Events.RemoveHandler (CheckedChangedEvent, value); }
393 public event EventHandler CheckStateChanged {
394 add { Events.AddHandler (CheckStateChangedEvent, value); }
395 remove {Events.RemoveHandler (CheckStateChangedEvent, value); }
399 #region Internal Properties
400 internal Form MdiClientForm {
401 get { return this.mdi_client_form; }
402 set { this.mdi_client_form = value; }
406 #region Internal Methods
407 internal override Size CalculatePreferredSize (Size constrainingSize)
409 Size base_size = base.CalculatePreferredSize (constrainingSize);
411 string key_string = GetShortcutDisplayString ();
413 if (string.IsNullOrEmpty (key_string))
416 Size text_size = TextRenderer.MeasureText (key_string, this.Font);
418 return new Size (base_size.Width + text_size.Width - 25, base_size.Height);
421 internal string GetShortcutDisplayString ()
423 if (this.show_shortcut_keys == false)
426 string key_string = string.Empty;
428 if (!string.IsNullOrEmpty (this.shortcut_display_string))
429 key_string = this.shortcut_display_string;
430 else if (this.shortcut_keys != Keys.None) {
431 KeysConverter kc = new KeysConverter ();
432 key_string = kc.ConvertToString (this.shortcut_keys);
438 internal void HandleAutoExpansion ()
440 if (this.HasDropDownItems) {
441 this.ShowDropDown ();
442 this.DropDown.SelectNextToolStripItem (null, true);
446 internal override void HandleClick (EventArgs e)