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;
34 namespace System.Windows.Forms
36 [DefaultEvent ("Click")]
37 [DefaultProperty ("Text")]
38 [DesignTimeVisible (false)]
40 public abstract class ToolStripItem : Component, IDropTarget, IComponent, IDisposable
42 #region Private Variables
43 private AccessibleObject accessibility_object;
44 private string accessible_default_action_description;
45 private bool allow_drop;
46 private ToolStripItemAlignment alignment;
47 private AnchorStyles anchor;
48 private bool available;
49 private bool auto_size;
50 private bool auto_tool_tip;
51 private Color back_color;
52 private Image background_image;
53 private ImageLayout background_image_layout;
54 private Rectangle bounds;
55 private bool can_select;
56 private ToolStripItemDisplayStyle display_style;
57 private DockStyle dock;
58 private bool double_click_enabled;
60 private Size explicit_size;
62 private Color fore_color;
64 private ContentAlignment image_align;
65 private int image_index;
66 private string image_key;
67 private ToolStripItemImageScaling image_scaling;
68 private Color image_transparent_color;
69 private bool is_disposed;
70 internal bool is_pressed;
71 private bool is_selected;
72 private Padding margin;
73 private MergeAction merge_action;
74 private int merge_index;
76 private ToolStripItemOverflow overflow;
77 private ToolStrip owner;
78 internal ToolStripItem owner_item;
79 private Padding padding;
80 private ToolStripItemPlacement placement;
81 private RightToLeft right_to_left;
82 private bool right_to_left_auto_mirror_image;
85 private ContentAlignment text_align;
86 private TextImageRelation text_image_relation;
87 private string tool_tip_text;
90 private ToolStrip parent;
91 private Size text_size;
94 #region Public Constructors
95 protected ToolStripItem ()
96 : this (String.Empty, null, null, String.Empty)
100 protected ToolStripItem (string text, Image image, EventHandler onClick)
101 : this (text, image, onClick, String.Empty)
105 protected ToolStripItem (string text, Image image, EventHandler onClick, string name)
107 this.alignment = ToolStripItemAlignment.Left;
108 this.anchor = AnchorStyles.Left | AnchorStyles.Top;
109 this.auto_size = true;
110 this.auto_tool_tip = this.DefaultAutoToolTip;
111 this.available = true;
112 this.back_color = Control.DefaultBackColor;
113 this.background_image_layout = ImageLayout.Tile;
114 this.can_select = true;
115 this.display_style = this.DefaultDisplayStyle;
116 this.dock = DockStyle.None;
118 this.font = new Font ("Tahoma", 8.25f);
119 this.fore_color = Control.DefaultForeColor;
121 this.image_align = ContentAlignment.MiddleCenter;
122 this.image_index = -1;
123 this.image_key = string.Empty;
124 this.image_scaling = ToolStripItemImageScaling.SizeToFit;
125 this.image_transparent_color = Color.Empty;
126 this.margin = this.DefaultMargin;
127 this.merge_action = MergeAction.Append;
128 this.merge_index = -1;
130 this.overflow = ToolStripItemOverflow.AsNeeded;
131 this.padding = this.DefaultPadding;
132 this.placement = ToolStripItemPlacement.None;
133 this.right_to_left = RightToLeft.Inherit;
134 this.bounds.Size = this.DefaultSize;
136 this.text_align = ContentAlignment.MiddleCenter;
137 this.text_image_relation = TextImageRelation.ImageBeforeText;
140 this.Click += onClick;
141 OnLayout (new LayoutEventArgs (null, string.Empty));
145 #region Public Properties
147 [EditorBrowsable (EditorBrowsableState.Advanced)]
148 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
149 public AccessibleObject AccessibilityObject {
151 if (this.accessibility_object == null)
152 this.accessibility_object = CreateAccessibilityInstance ();
154 return this.accessibility_object;
159 [EditorBrowsable (EditorBrowsableState.Advanced)]
160 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
161 public string AccessibleDefaultActionDescription {
163 if (this.accessibility_object == null)
166 return this.accessible_default_action_description;
168 set { this.accessible_default_action_description = value; }
172 [DefaultValue (null)]
173 public string AccessibleDescription {
175 if (this.accessibility_object == null)
178 return this.AccessibilityObject.Description;
180 set { this.AccessibilityObject.description = value; }
184 [DefaultValue (null)]
185 public string AccessibleName {
187 if (this.accessibility_object == null)
190 return this.AccessibilityObject.Name;
192 set { this.AccessibilityObject.Name = value; }
195 [DefaultValue (AccessibleRole.Default)]
196 public AccessibleRole AccessibleRole {
199 if (this.accessibility_object == null)
200 return AccessibleRole.Default;
202 return this.AccessibilityObject.Role;
204 set { this.AccessibilityObject.role = value; }
207 [DefaultValue (ToolStripItemAlignment.Left)]
208 public ToolStripItemAlignment Alignment {
209 get { return this.alignment; }
211 if (!Enum.IsDefined (typeof (ToolStripItemAlignment), value))
212 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemAlignment", value));
214 this.alignment = value;
219 public virtual bool AllowDrop {
221 return this.allow_drop;
225 this.allow_drop = value;
230 [DefaultValue (AnchorStyles.Top | AnchorStyles.Left)]
231 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
232 public AnchorStyles Anchor {
233 get { return this.anchor; }
234 set { this.anchor = value; }
238 [DefaultValue (true)]
239 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
240 [RefreshProperties (RefreshProperties.All)]
241 public bool AutoSize {
242 get { return this.auto_size; }
244 this.auto_size = value;
245 this.CalculateAutoSize ();
249 [DefaultValue (false)]
250 public bool AutoToolTip {
251 get { return this.auto_tool_tip; }
252 set { this.auto_tool_tip = value; }
256 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
257 public bool Available {
258 get { return this.available; }
260 if (this.available != value) {
264 if (this.parent != null)
265 parent.PerformLayout ();
267 OnAvailableChanged (EventArgs.Empty);
268 OnVisibleChanged (EventArgs.Empty);
273 public virtual Color BackColor {
274 get { return this.back_color; }
276 if (this.back_color != value) {
278 OnBackColorChanged (EventArgs.Empty);
285 [DefaultValue (null)]
286 public virtual Image BackgroundImage {
287 get { return this.background_image; }
289 if (this.background_image != value) {
290 this.background_image = value;
297 [DefaultValue (ImageLayout.Tile)]
298 public virtual ImageLayout BackgroundImageLayout {
299 get { return this.background_image_layout; }
301 if (this.background_image_layout != value) {
302 this.background_image_layout = value;
309 public virtual Rectangle Bounds {
310 get { return this.bounds; }
314 public virtual bool CanSelect {
315 get { return this.can_select; }
319 public Rectangle ContentRectangle {
321 // ToolStripLabels don't have a border
322 if (this is ToolStripLabel || this is ToolStripStatusLabel)
323 return new Rectangle (0, 0, this.bounds.Width, this.bounds.Height);
325 if (this is ToolStripDropDownButton && (this as ToolStripDropDownButton).ShowDropDownArrow)
326 return new Rectangle (2, 2, this.bounds.Width - 13, this.bounds.Height - 4);
328 return new Rectangle (2, 2, this.bounds.Width - 4, this.bounds.Height - 4);
332 public virtual ToolStripItemDisplayStyle DisplayStyle {
333 get { return this.display_style; }
335 if (this.display_style != value) {
336 this.display_style = value;
337 this.CalculateAutoSize ();
338 OnDisplayStyleChanged (EventArgs.Empty);
339 if (this.Parent != null)
340 this.Parent.PerformLayout ();
345 public bool IsDisposed {
346 get { return this.is_disposed; }
350 [DefaultValue (DockStyle.None)]
351 public DockStyle Dock {
352 get { return this.dock; }
354 if (this.dock != value) {
355 if (!Enum.IsDefined (typeof (DockStyle), value))
356 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for DockStyle", value));
359 this.CalculateAutoSize ();
364 [DefaultValue (false)]
365 public bool DoubleClickEnabled {
366 get { return this.double_click_enabled; }
367 set { this.double_click_enabled = value; }
371 [DefaultValue (true)]
372 public virtual bool Enabled {
373 get { return enabled; }
375 if (this.enabled != value) {
376 this.enabled = value;
377 OnEnabledChanged (EventArgs.Empty);
384 public virtual Font Font
386 get { return this.font; }
388 if (this.font != value) {
390 this.CalculateAutoSize ();
391 this.OnFontChanged (EventArgs.Empty);
397 public virtual Color ForeColor {
398 get { return this.fore_color; }
400 if (this.fore_color != value) {
401 this.fore_color = value;
402 this.OnForeColorChanged (EventArgs.Empty);
409 [EditorBrowsable (EditorBrowsableState.Always)]
410 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
412 get { return this.Size.Height; }
414 this.bounds.Height = value;
415 this.explicit_size.Height = value;
418 this.CalculateAutoSize ();
419 this.OnBoundsChanged ();
426 public virtual Image Image {
428 if (this.image != null)
431 if (this.image_index >= 0)
432 if (this.owner != null && this.owner.ImageList != null)
433 return this.owner.ImageList.Images[this.image_index];
436 if (!string.IsNullOrEmpty (this.image_key))
437 if (this.owner != null && this.owner.ImageList != null)
438 return this.owner.ImageList.Images[this.image_key];
443 if (this.image != value) {
445 this.image_index = -1;
446 this.image_key = string.Empty;
447 this.CalculateAutoSize ();
454 [DefaultValue (ContentAlignment.MiddleCenter)]
455 public ContentAlignment ImageAlign {
456 get { return this.image_align; }
458 if (!Enum.IsDefined (typeof (ContentAlignment), value))
459 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
461 this.image_align = value;
468 [RelatedImageList ("Owner.ImageList")]
469 [RefreshProperties (RefreshProperties.Repaint)]
470 public int ImageIndex {
471 get { return this.image_index; }
473 if (this.image_index != value) {
474 // Lamespec: MSDN says ArgumentException, tests say otherwise
476 throw new ArgumentOutOfRangeException ("ImageIndex cannot be less than -1");
478 this.image_index = value;
480 this.image_key = string.Empty;
481 this.CalculateAutoSize ();
489 [RelatedImageList ("Owner.ImageList")]
490 [RefreshProperties (RefreshProperties.Repaint)]
491 public string ImageKey
493 get { return this.image_key; }
495 if (this.image_key != value) {
497 this.image_index = -1;
498 this.image_key = value;
499 this.CalculateAutoSize ();
506 [DefaultValue (ToolStripItemImageScaling.SizeToFit)]
507 public ToolStripItemImageScaling ImageScaling {
508 get { return this.image_scaling; }
510 this.image_scaling = value;
511 this.CalculateAutoSize ();
517 public Color ImageTransparentColor {
518 get { return this.image_transparent_color; }
519 set { this.image_transparent_color = value; }
523 public bool IsOnDropDown {
525 if (this.parent != null && this.parent is ToolStripDropDown)
533 public bool IsOnOverflow {
534 get { return this.placement == ToolStripItemPlacement.Overflow; }
537 public Padding Margin {
538 get { return this.margin; }
541 this.CalculateAutoSize ();
545 [DefaultValue (MergeAction.Append)]
546 public MergeAction MergeAction {
547 get { return this.merge_action; }
549 if (!Enum.IsDefined (typeof (MergeAction), value))
550 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for MergeAction", value));
552 this.merge_action = value;
557 public int MergeIndex {
558 get { return this.merge_index; }
559 set { this.merge_index = value; }
562 [DefaultValue (null)]
565 get { return this.name; }
566 set { this.name = value; }
569 [DefaultValue (ToolStripItemOverflow.AsNeeded)]
570 public ToolStripItemOverflow Overflow {
571 get { return this.overflow; }
573 if (this.overflow != value) {
574 if (!Enum.IsDefined (typeof (ToolStripItemOverflow), value))
575 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemOverflow", value));
577 this.overflow = value;
580 owner.PerformLayout ();
586 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
587 public ToolStrip Owner {
588 get { return this.owner; }
590 if (this.owner != value) {
592 this.CalculateAutoSize ();
593 OnOwnerChanged (EventArgs.Empty);
599 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
600 public ToolStripItem OwnerItem {
601 get { return this.owner_item; }
604 public virtual Padding Padding {
605 get { return this.padding; }
607 this.padding = value;
608 this.CalculateAutoSize ();
614 public ToolStripItemPlacement Placement {
615 get { return this.placement; }
619 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
620 public virtual bool Pressed { get { return this.is_pressed; } }
622 [MonoTODO ("Stub, not implemented")]
624 public virtual RightToLeft RightToLeft {
625 get { return this.right_to_left; }
627 if (this.right_to_left != value) {
628 this.right_to_left = value;
629 this.OnRightToLeftChanged (EventArgs.Empty);
635 public bool RightToLeftAutoMirrorImage {
636 get { return this.right_to_left_auto_mirror_image; }
638 if (this.right_to_left_auto_mirror_image != value) {
639 this.right_to_left_auto_mirror_image = value;
646 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
647 public virtual bool Selected { get { return this.is_selected; } }
650 public virtual Size Size {
652 if (!this.AutoSize && this.explicit_size != Size.Empty)
653 return this.explicit_size;
655 return this.bounds.Size;
658 this.bounds.Size = value;
659 this.explicit_size = value;
662 this.CalculateAutoSize ();
663 this.OnBoundsChanged ();
668 [Localizable (false)]
670 [DefaultValue (null)]
671 [TypeConverter (typeof (StringConverter))]
673 get { return this.tag; }
674 set { this.tag = value; }
679 public virtual string Text
681 get { return this.text; }
683 if (this.text != value) {
685 this.CalculateAutoSize ();
686 this.OnTextChanged (EventArgs.Empty);
693 [DefaultValue (ContentAlignment.MiddleCenter)]
694 public virtual ContentAlignment TextAlign {
695 get { return this.text_align; }
697 if (!Enum.IsDefined (typeof (ContentAlignment), value))
698 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
699 this.text_align = value;
705 [DefaultValue (TextImageRelation.ImageBeforeText)]
706 public TextImageRelation TextImageRelation {
707 get { return this.text_image_relation; }
709 this.text_image_relation = value;
710 this.CalculateAutoSize ();
716 public string ToolTipText {
717 get { return this.tool_tip_text; }
718 set { this.tool_tip_text = value; }
722 public bool Visible {
724 if (this.parent == null)
727 return this.visible && this.parent.Visible;
730 if (this.visible != value) {
731 this.available = value;
732 this.SetVisibleCore (value);
738 [EditorBrowsable (EditorBrowsableState.Always)]
739 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
741 get { return this.Size.Width; }
743 this.bounds.Width = value;
744 this.explicit_size.Width = value;
747 this.CalculateAutoSize ();
748 this.OnBoundsChanged ();
755 #region Protected Properties
756 protected virtual bool DefaultAutoToolTip { get { return false; } }
757 protected virtual ToolStripItemDisplayStyle DefaultDisplayStyle { get { return ToolStripItemDisplayStyle.ImageAndText; } }
758 protected internal virtual Padding DefaultMargin { get { return new Padding (0, 1, 0, 2); } }
759 protected virtual Padding DefaultPadding { get { return new Padding (); } }
760 protected virtual Size DefaultSize { get { return new Size (23, 23); } }
761 protected internal virtual bool DismissWhenClicked { get { return true; } }
763 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
764 protected internal ToolStrip Parent {
765 get { return this.parent; }
767 if (this.parent != value) {
768 ToolStrip old_parent = this.parent;
770 OnParentChanged(old_parent, this.parent);
774 protected internal virtual bool ShowKeyboardCues { get { return false; } }
777 #region Public Methods
778 public ToolStrip GetCurrentParent ()
783 public virtual Size GetPreferredSize (Size constrainingSize)
785 return this.CalculatePreferredSize (constrainingSize);
788 public void Invalidate ()
791 parent.Invalidate (this.bounds);
794 public void Invalidate (Rectangle r)
797 parent.Invalidate (r);
800 public void PerformClick ()
802 this.OnClick (EventArgs.Empty);
805 [EditorBrowsable (EditorBrowsableState.Never)]
806 public virtual void ResetBackColor () { this.BackColor = Control.DefaultBackColor; }
808 [EditorBrowsable (EditorBrowsableState.Never)]
809 public virtual void ResetDisplayStyle () { this.display_style = this.DefaultDisplayStyle; }
811 [EditorBrowsable (EditorBrowsableState.Never)]
812 public virtual void ResetFont () { this.font = new Font ("Tahoma", 8.25f); }
814 [EditorBrowsable (EditorBrowsableState.Never)]
815 public virtual void ResetForeColor () { this.ForeColor = Control.DefaultForeColor; }
817 [EditorBrowsable (EditorBrowsableState.Never)]
818 public virtual void ResetImage () { this.image = null; }
820 [EditorBrowsable (EditorBrowsableState.Never)]
821 public void ResetMargin () { this.margin = this.DefaultMargin; }
823 [EditorBrowsable (EditorBrowsableState.Never)]
824 public void ResetPadding () { this.padding = this.DefaultPadding; }
826 public void Select ()
828 if (!this.is_selected && this.CanSelect) {
829 this.is_selected = true;
831 this.Parent.NotifySelectedChanged (this);
835 public override string ToString ()
841 #region Protected Methods
842 [EditorBrowsable (EditorBrowsableState.Advanced)]
843 protected virtual AccessibleObject CreateAccessibilityInstance ()
845 return new ToolStripItemAccessibleObject (this);
848 protected override void Dispose (bool disposing)
850 if (!is_disposed && disposing)
853 base.Dispose (disposing);
856 protected internal virtual bool IsInputChar (char charCode)
861 protected internal virtual bool IsInputKey (Keys keyData)
866 protected virtual void OnAvailableChanged (EventArgs e)
868 EventHandler eh = (EventHandler)(Events [AvailableChangedEvent]);
873 [EditorBrowsable (EditorBrowsableState.Advanced)]
874 protected virtual void OnBackColorChanged (EventArgs e)
876 EventHandler eh = (EventHandler)(Events [BackColorChangedEvent]);
881 protected virtual void OnBoundsChanged ()
883 OnLayout (new LayoutEventArgs(null, string.Empty));
886 protected virtual void OnClick (EventArgs e)
888 EventHandler eh = (EventHandler)(Events [ClickEvent]);
893 [EditorBrowsable (EditorBrowsableState.Advanced)]
894 protected virtual void OnDisplayStyleChanged (EventArgs e)
896 EventHandler eh = (EventHandler)(Events [DisplayStyleChangedEvent]);
901 protected virtual void OnDoubleClick (EventArgs e)
903 EventHandler eh = (EventHandler)(Events [DoubleClickEvent]);
907 if (!double_click_enabled)
911 void IDropTarget.OnDragDrop (DragEventArgs e)
916 void IDropTarget.OnDragEnter (DragEventArgs e)
921 void IDropTarget.OnDragLeave (EventArgs e)
926 void IDropTarget.OnDragOver (DragEventArgs e)
931 protected virtual void OnEnabledChanged (EventArgs e)
933 EventHandler eh = (EventHandler)(Events [EnabledChangedEvent]);
938 [EditorBrowsable (EditorBrowsableState.Advanced)]
939 protected virtual void OnFontChanged (EventArgs e)
943 [EditorBrowsable (EditorBrowsableState.Advanced)]
944 protected virtual void OnForeColorChanged (EventArgs e)
946 EventHandler eh = (EventHandler)(Events [ForeColorChangedEvent]);
951 protected virtual void OnLayout (LayoutEventArgs e)
955 protected virtual void OnLocationChanged (EventArgs e)
957 EventHandler eh = (EventHandler)(Events [LocationChangedEvent]);
962 protected virtual void OnMouseDown (MouseEventArgs e)
965 this.is_pressed = true;
968 MouseEventHandler eh = (MouseEventHandler)(Events [MouseDownEvent]);
974 protected virtual void OnMouseEnter (EventArgs e)
978 EventHandler eh = (EventHandler)(Events [MouseEnterEvent]);
983 protected virtual void OnMouseHover (EventArgs e)
986 EventHandler eh = (EventHandler)(Events [MouseHoverEvent]);
992 protected virtual void OnMouseLeave (EventArgs e)
994 if (this.CanSelect) {
995 this.is_selected = false;
996 this.is_pressed = false;
1000 EventHandler eh = (EventHandler)(Events [MouseLeaveEvent]);
1005 protected virtual void OnMouseMove (MouseEventArgs e)
1008 MouseEventHandler eh = (MouseEventHandler)(Events [MouseMoveEvent]);
1014 protected virtual void OnMouseUp (MouseEventArgs e)
1017 this.is_pressed = false;
1020 if (this.IsOnDropDown)
1021 if (!(this is ToolStripDropDownItem) || !(this as ToolStripDropDownItem).HasDropDownItems || (this as ToolStripDropDownItem).DropDown.Visible == false) {
1022 if ((this.Parent as ToolStripDropDown).OwnerItem != null)
1023 ((this.Parent as ToolStripDropDown).OwnerItem as ToolStripDropDownItem).HideDropDown ();
1025 (this.Parent as ToolStripDropDown).Hide ();
1029 MouseEventHandler eh = (MouseEventHandler)(Events [MouseUpEvent]);
1035 protected virtual void OnOwnerChanged (EventArgs e)
1037 EventHandler eh = (EventHandler)(Events [OwnerChangedEvent]);
1042 protected internal virtual void OnOwnerFontChanged (EventArgs e)
1046 protected virtual void OnPaint (PaintEventArgs e)
1048 if (this.parent != null)
1049 this.parent.Renderer.DrawItemBackground (new ToolStripItemRenderEventArgs (e.Graphics, this));
1051 PaintEventHandler eh = (PaintEventHandler)(Events [PaintEvent]);
1056 // This is never called.
1057 protected virtual void OnParentBackColorChanged (EventArgs e)
1061 protected virtual void OnParentChanged (ToolStrip oldParent, ToolStrip newParent)
1063 if (oldParent != null)
1064 oldParent.PerformLayout ();
1066 if (newParent != null)
1067 newParent.PerformLayout ();
1070 protected internal virtual void OnParentEnabledChanged (EventArgs e)
1072 this.OnEnabledChanged (e);
1075 // This is never called.
1076 protected virtual void OnParentForeColorChanged (EventArgs e)
1080 protected internal virtual void OnParentRightToLeftChanged (EventArgs e)
1082 this.OnRightToLeftChanged (e);
1085 protected virtual void OnRightToLeftChanged (EventArgs e)
1087 EventHandler eh = (EventHandler)(Events[RightToLeftChangedEvent]);
1092 [EditorBrowsable (EditorBrowsableState.Advanced)]
1093 protected virtual void OnTextChanged (EventArgs e)
1095 EventHandler eh = (EventHandler)(Events [TextChangedEvent]);
1100 protected virtual void OnVisibleChanged (EventArgs e)
1102 EventHandler eh = (EventHandler)(Events [VisibleChangedEvent]);
1107 protected internal virtual bool ProcessCmdKey (ref Message m, Keys keyData)
1112 protected internal virtual bool ProcessDialogKey (Keys keyData)
1114 if (this.Selected && keyData == Keys.Enter) {
1115 this.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click);
1122 protected internal virtual bool ProcessMnemonic (char charCode)
1127 protected internal virtual void SetBounds (Rectangle bounds)
1129 if (this.bounds != bounds) {
1130 this.bounds = bounds;
1135 protected virtual void SetVisibleCore (bool visible)
1137 this.visible = visible;
1138 this.OnVisibleChanged (EventArgs.Empty);
1143 #region Public Events
1144 static object AvailableChangedEvent = new object ();
1145 static object BackColorChangedEvent = new object ();
1146 static object ClickEvent = new object ();
1147 static object DisplayStyleChangedEvent = new object ();
1148 static object DoubleClickEvent = new object ();
1149 static object EnabledChangedEvent = new object ();
1150 static object ForeColorChangedEvent = new object ();
1151 static object LocationChangedEvent = new object ();
1152 static object MouseDownEvent = new object ();
1153 static object MouseEnterEvent = new object ();
1154 static object MouseHoverEvent = new object ();
1155 static object MouseLeaveEvent = new object ();
1156 static object MouseMoveEvent = new object ();
1157 static object MouseUpEvent = new object ();
1158 static object OwnerChangedEvent = new object ();
1159 static object PaintEvent = new object ();
1160 static object RightToLeftChangedEvent = new object ();
1161 static object TextChangedEvent = new object ();
1162 static object VisibleChangedEvent = new object ();
1165 public event EventHandler AvailableChanged {
1166 add { Events.AddHandler (AvailableChangedEvent, value); }
1167 remove {Events.RemoveHandler (AvailableChangedEvent, value); }
1170 public event EventHandler BackColorChanged {
1171 add { Events.AddHandler (BackColorChangedEvent, value); }
1172 remove {Events.RemoveHandler (BackColorChangedEvent, value); }
1175 public event EventHandler Click {
1176 add { Events.AddHandler (ClickEvent, value); }
1177 remove {Events.RemoveHandler (ClickEvent, value); }
1180 public event EventHandler DisplayStyleChanged {
1181 add { Events.AddHandler (DisplayStyleChangedEvent, value); }
1182 remove {Events.RemoveHandler (DisplayStyleChangedEvent, value); }
1185 public event EventHandler DoubleClick {
1186 add { Events.AddHandler (DoubleClickEvent, value); }
1187 remove {Events.RemoveHandler (DoubleClickEvent, value); }
1190 public event EventHandler EnabledChanged {
1191 add { Events.AddHandler (EnabledChangedEvent, value); }
1192 remove {Events.RemoveHandler (EnabledChangedEvent, value); }
1195 public event EventHandler ForeColorChanged {
1196 add { Events.AddHandler (ForeColorChangedEvent, value); }
1197 remove {Events.RemoveHandler (ForeColorChangedEvent, value); }
1200 public event EventHandler LocationChanged {
1201 add { Events.AddHandler (LocationChangedEvent, value); }
1202 remove {Events.RemoveHandler (LocationChangedEvent, value); }
1205 public event MouseEventHandler MouseDown {
1206 add { Events.AddHandler (MouseDownEvent, value); }
1207 remove {Events.RemoveHandler (MouseDownEvent, value); }
1210 public event EventHandler MouseEnter {
1211 add { Events.AddHandler (MouseEnterEvent, value); }
1212 remove {Events.RemoveHandler (MouseEnterEvent, value); }
1215 public event EventHandler MouseHover {
1216 add { Events.AddHandler (MouseHoverEvent, value); }
1217 remove {Events.RemoveHandler (MouseHoverEvent, value); }
1220 public event EventHandler MouseLeave {
1221 add { Events.AddHandler (MouseLeaveEvent, value); }
1222 remove {Events.RemoveHandler (MouseLeaveEvent, value); }
1225 public event MouseEventHandler MouseMove {
1226 add { Events.AddHandler (MouseMoveEvent, value); }
1227 remove {Events.RemoveHandler (MouseMoveEvent, value); }
1230 public event MouseEventHandler MouseUp {
1231 add { Events.AddHandler (MouseUpEvent, value); }
1232 remove {Events.RemoveHandler (MouseUpEvent, value); }
1235 public event EventHandler OwnerChanged {
1236 add { Events.AddHandler (OwnerChangedEvent, value); }
1237 remove {Events.RemoveHandler (OwnerChangedEvent, value); }
1240 public event PaintEventHandler Paint {
1241 add { Events.AddHandler (PaintEvent, value); }
1242 remove {Events.RemoveHandler (PaintEvent, value); }
1245 public event EventHandler RightToLeftChanged {
1246 add { Events.AddHandler (RightToLeftChangedEvent, value); }
1247 remove { Events.RemoveHandler (RightToLeftChangedEvent, value); }
1250 public event EventHandler TextChanged {
1251 add { Events.AddHandler (TextChangedEvent, value); }
1252 remove {Events.RemoveHandler (TextChangedEvent, value); }
1255 public event EventHandler VisibleChanged {
1256 add { Events.AddHandler (VisibleChangedEvent, value); }
1257 remove {Events.RemoveHandler (VisibleChangedEvent, value); }
1261 #region Internal Methods
1262 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, ContentAlignment align)
1267 if (align == ContentAlignment.BottomLeft || align == ContentAlignment.MiddleLeft || align == ContentAlignment.TopLeft)
1269 else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.MiddleCenter || align == ContentAlignment.TopCenter)
1270 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
1271 else if (align == ContentAlignment.BottomRight || align == ContentAlignment.MiddleRight || align == ContentAlignment.TopRight)
1272 x = outer.Right - inner.Width;
1273 if (align == ContentAlignment.TopCenter || align == ContentAlignment.TopLeft || align == ContentAlignment.TopRight)
1275 else if (align == ContentAlignment.MiddleCenter || align == ContentAlignment.MiddleLeft || align == ContentAlignment.MiddleRight)
1276 y = outer.Y + (outer.Height - inner.Height) / 2;
1277 else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.BottomRight || align == ContentAlignment.BottomLeft)
1278 y = outer.Bottom - inner.Height;
1280 return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
1283 internal void CalculateAutoSize ()
1285 this.text_size = TextRenderer.MeasureText (this.Text == null ? string.Empty: this.text, this.Font, Size.Empty, TextFormatFlags.HidePrefix);
1287 if (!this.auto_size || this is ToolStripControlHost)
1289 //this.text_size.Width += 6;
1291 Size final_size = this.CalculatePreferredSize (Size.Empty);
1293 if (final_size != this.Size) {
1294 this.bounds.Width = final_size.Width;
1295 if (this.parent != null)
1296 this.parent.PerformLayout ();
1300 internal virtual Size CalculatePreferredSize (Size constrainingSize)
1302 if (!this.auto_size)
1303 return this.explicit_size;
1305 Size preferred_size = this.DefaultSize;
1307 switch (this.display_style) {
1308 case ToolStripItemDisplayStyle.Text:
1309 int width = text_size.Width + this.padding.Horizontal;
1310 int height = text_size.Height + this.padding.Vertical;
1311 preferred_size = new Size (width, height);
1313 case ToolStripItemDisplayStyle.Image:
1314 if (this.Image == null)
1315 preferred_size = this.DefaultSize;
1317 switch (this.image_scaling) {
1318 case ToolStripItemImageScaling.None:
1319 preferred_size = this.Image.Size;
1321 case ToolStripItemImageScaling.SizeToFit:
1322 if (this.parent == null)
1323 preferred_size = this.Image.Size;
1325 preferred_size = this.parent.ImageScalingSize;
1330 case ToolStripItemDisplayStyle.ImageAndText:
1331 int width2 = text_size.Width + this.padding.Horizontal;
1332 int height2 = text_size.Height + this.padding.Vertical;
1334 if (this.Image != null) {
1335 switch (this.text_image_relation) {
1336 case TextImageRelation.Overlay:
1337 width2 = Math.Max (width2, this.Image.Width);
1338 height2 = Math.Max (height2, this.Image.Height);
1340 case TextImageRelation.ImageAboveText:
1341 case TextImageRelation.TextAboveImage:
1342 width2 = Math.Max (width2, this.Image.Width);
1343 height2 += this.Image.Height;
1345 case TextImageRelation.ImageBeforeText:
1346 case TextImageRelation.TextBeforeImage:
1347 height2 = Math.Max (height2, this.Image.Height);
1348 width2 += this.Image.Width;
1353 preferred_size = new Size (width2, height2);
1357 if (!(this is ToolStripLabel)) { // Everything but labels have a border
1358 preferred_size.Height += 4;
1359 preferred_size.Width += 4;
1362 // Account for ToolStripDropDownButton's drop down arrow
1363 if (this is ToolStripDropDownButton && (this as ToolStripDropDownButton).ShowDropDownArrow)
1364 preferred_size.Width += 9;
1366 return preferred_size;
1369 internal void CalculateTextAndImageRectangles (out Rectangle text_rect, out Rectangle image_rect)
1371 this.CalculateTextAndImageRectangles (this.ContentRectangle, out text_rect, out image_rect);
1374 internal void CalculateTextAndImageRectangles (Rectangle contentRectangle, out Rectangle text_rect, out Rectangle image_rect)
1376 text_rect = Rectangle.Empty;
1377 image_rect = Rectangle.Empty;
1379 switch (this.display_style) {
1380 case ToolStripItemDisplayStyle.None:
1382 case ToolStripItemDisplayStyle.Text:
1383 if (this.text != string.Empty)
1384 text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align);
1386 case ToolStripItemDisplayStyle.Image:
1387 if (this.Image != null)
1388 image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align);
1390 case ToolStripItemDisplayStyle.ImageAndText:
1391 if (this.text != string.Empty && this.Image == null)
1392 text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align);
1393 else if (this.text == string.Empty && this.Image != null)
1394 image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align);
1395 else if (this.text == string.Empty && this.Image == null)
1398 Rectangle text_area;
1399 Rectangle image_area;
1401 switch (this.text_image_relation) {
1402 case TextImageRelation.Overlay:
1403 text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align);
1404 image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align);
1406 case TextImageRelation.ImageAboveText:
1407 text_area = new Rectangle (contentRectangle.Left, contentRectangle.Bottom - (text_size.Height - 4), contentRectangle.Width, text_size.Height - 4);
1408 image_area = new Rectangle (contentRectangle.Left, contentRectangle.Top, contentRectangle.Width, contentRectangle.Height - text_area.Height);
1410 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
1411 image_rect = AlignInRectangle (image_area, GetImageSize (), this.image_align);
1413 case TextImageRelation.TextAboveImage:
1414 text_area = new Rectangle (contentRectangle.Left, contentRectangle.Top, contentRectangle.Width, text_size.Height - 4);
1415 image_area = new Rectangle (contentRectangle.Left, text_area.Bottom, contentRectangle.Width, contentRectangle.Height - text_area.Height);
1417 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
1418 image_rect = AlignInRectangle (image_area, GetImageSize (), this.image_align);
1420 case TextImageRelation.ImageBeforeText:
1421 LayoutTextBeforeOrAfterImage (contentRectangle, false, text_size, GetImageSize (), text_align, image_align, out text_rect, out image_rect);
1423 case TextImageRelation.TextBeforeImage:
1424 LayoutTextBeforeOrAfterImage (contentRectangle, true, text_size, GetImageSize (), text_align, image_align, out text_rect, out image_rect);
1432 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1435 this.is_selected = false;
1440 internal virtual ToolStrip GetTopLevelToolStrip ()
1442 if (this.Parent != null)
1443 return this.Parent.GetTopLevelToolStrip ();
1448 private void LayoutTextBeforeOrAfterImage (Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, ContentAlignment textAlign, ContentAlignment imageAlign, out Rectangle textRect, out Rectangle imageRect)
1450 int element_spacing = 0; // Spacing between the Text and the Image
1451 int total_width = textSize.Width + element_spacing + imageSize.Width;
1452 int excess_width = totalArea.Width - total_width;
1455 Rectangle final_text_rect;
1456 Rectangle final_image_rect;
1458 HorizontalAlignment h_text = GetHorizontalAlignment (textAlign);
1459 HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign);
1461 if (h_image == HorizontalAlignment.Left)
1463 else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right)
1464 offset = excess_width;
1465 else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center))
1466 offset += (int)(excess_width / 3);
1468 offset += (int)(2 * (excess_width / 3));
1471 final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
1472 final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
1474 final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
1475 final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
1478 textRect = final_text_rect;
1479 imageRect = final_image_rect;
1482 private HorizontalAlignment GetHorizontalAlignment (ContentAlignment align)
1485 case ContentAlignment.BottomLeft:
1486 case ContentAlignment.MiddleLeft:
1487 case ContentAlignment.TopLeft:
1488 return HorizontalAlignment.Left;
1489 case ContentAlignment.BottomCenter:
1490 case ContentAlignment.MiddleCenter:
1491 case ContentAlignment.TopCenter:
1492 return HorizontalAlignment.Center;
1493 case ContentAlignment.BottomRight:
1494 case ContentAlignment.MiddleRight:
1495 case ContentAlignment.TopRight:
1496 return HorizontalAlignment.Right;
1499 return HorizontalAlignment.Left;
1502 internal Size GetImageSize ()
1504 if (this.Image == null)
1507 if (this.image_scaling == ToolStripItemImageScaling.None)
1508 return this.Image.Size;
1510 if (this.Parent == null)
1513 return this.Parent.ImageScalingSize;
1516 internal string GetToolTip ()
1518 if (this.auto_tool_tip && string.IsNullOrEmpty (this.tool_tip_text))
1521 return this.tool_tip_text;
1524 internal void FireEvent (EventArgs e, ToolStripItemEventType met)
1526 // If we're disabled, don't fire any of these events, except Paint
1527 if (!this.Enabled && met != ToolStripItemEventType.Paint)
1531 case ToolStripItemEventType.MouseUp:
1532 this.OnMouseUp ((MouseEventArgs)e);
1533 this.HandleClick (e);
1535 case ToolStripItemEventType.MouseDown:
1536 this.OnMouseDown ((MouseEventArgs)e);
1538 case ToolStripItemEventType.MouseEnter:
1539 this.OnMouseEnter (e);
1541 case ToolStripItemEventType.MouseHover:
1542 this.OnMouseHover (e);
1544 case ToolStripItemEventType.MouseLeave:
1545 this.OnMouseLeave (e);
1547 case ToolStripItemEventType.MouseMove:
1548 this.OnMouseMove ((MouseEventArgs)e);
1550 case ToolStripItemEventType.Paint:
1551 this.OnPaint ((PaintEventArgs)e);
1553 case ToolStripItemEventType.Click:
1554 this.HandleClick (e);
1559 internal virtual void HandleClick (EventArgs e)
1561 this.Parent.HandleItemClick (this);
1565 internal virtual void SetPlacement (ToolStripItemPlacement placement)
1567 this.placement = placement;
1570 internal bool InternalVisible {
1571 get { return this.visible; }
1572 set { this.visible = value; }
1575 internal Point Location {
1576 get { return this.bounds.Location; }
1578 if (this.bounds.Location != value) {
1579 this.bounds.Location = value;
1580 this.OnLocationChanged (EventArgs.Empty);
1586 get { return this.bounds.Y; }
1588 if (this.bounds.Y != value) {
1589 this.bounds.Y = value;
1590 this.OnLocationChanged (EventArgs.Empty);
1596 get { return this.bounds.X; }
1598 if (this.bounds.X != value) {
1599 this.bounds.X = value;
1600 this.OnLocationChanged (EventArgs.Empty);
1605 internal int Right { get { return this.bounds.Right; } }
1606 internal int Bottom { get { return this.bounds.Bottom; } }
1609 public class ToolStripItemAccessibleObject : AccessibleObject
1611 private ToolStripItem owner_item;
1613 public ToolStripItemAccessibleObject (ToolStripItem ownerItem)
1615 if (ownerItem == null)
1616 throw new ArgumentNullException ("ownerItem");
1618 this.owner_item = ownerItem;
1619 base.default_action = string.Empty;
1620 base.keyboard_shortcut = string.Empty;
1621 base.name = string.Empty;
1622 base.value = string.Empty;
1625 #region Public Properties
1626 public override Rectangle Bounds {
1628 return owner_item.Visible ? owner_item.Bounds : Rectangle.Empty;
1632 public override string DefaultAction {
1633 get { return base.DefaultAction; }
1636 public override string Description {
1637 get { return base.Description; }
1640 public override string Help {
1641 get { return base.Help; }
1644 public override string KeyboardShortcut {
1645 get { return base.KeyboardShortcut; }
1648 public override string Name {
1650 if (base.name == string.Empty)
1651 return owner_item.Text;
1655 set { base.Name = value; }
1658 public override AccessibleObject Parent {
1659 get { return base.Parent; }
1662 public override AccessibleRole Role {
1663 get { return base.Role; }
1666 public override AccessibleStates State {
1667 get { return base.State; }
1671 #region Public Methods
1672 public void AddState (AccessibleStates state)
1677 public override void DoDefaultAction ()
1679 base.DoDefaultAction ();
1682 public override int GetHelpTopic (out string FileName)
1684 return base.GetHelpTopic (out FileName);
1687 public override AccessibleObject Navigate (AccessibleNavigation navdir)
1689 return base.Navigate (navdir);
1692 public override string ToString ()
1694 return string.Format ("ToolStripItemAccessibleObject: Owner = {0}", owner_item.ToString());