1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2008 Novell, Inc.
23 // Jonathan Chambers (jonathan.chambers@ansys.com)
24 // Ivan N. Zlatev (contact@i-nz.net)
32 using System.Drawing.Design;
33 using System.ComponentModel;
34 using System.Collections;
35 using System.ComponentModel.Design;
36 using System.Reflection;
37 using System.Runtime.InteropServices;
38 using System.Windows.Forms.Design;
39 using System.Windows.Forms.PropertyGridInternal;
41 namespace System.Windows.Forms
43 [Designer("System.Windows.Forms.Design.PropertyGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45 [ClassInterface (ClassInterfaceType.AutoDispatch)]
48 public class PropertyGrid : System.Windows.Forms.ContainerControl, ComponentModel.Com2Interop.IComPropertyBrowser
50 #region Private Members
53 private const string UNCATEGORIZED_CATEGORY_LABEL = "Misc";
54 private AttributeCollection browsable_attributes = null;
55 private bool can_show_commands = false;
56 private Color commands_back_color;
57 private Color commands_fore_color;
58 private bool commands_visible;
59 private bool commands_visible_if_available;
60 private Point context_menu_default_location;
61 private bool large_buttons;
62 private Color line_color;
63 private PropertySort property_sort;
64 private PropertyTabCollection property_tabs;
65 private GridEntry selected_grid_item;
66 private GridEntry root_grid_item;
67 private object[] selected_objects;
68 private PropertyTab properties_tab;
69 private PropertyTab selected_tab;
71 private ImageList toolbar_imagelist;
72 private Image categorized_image;
73 private Image alphabetical_image;
74 private Image propertypages_image;
75 private PropertyToolBarButton categorized_toolbarbutton;
76 private PropertyToolBarButton alphabetic_toolbarbutton;
77 private PropertyToolBarButton propertypages_toolbarbutton;
78 private PropertyToolBarSeparator separator_toolbarbutton;
79 private PropertyToolBarButton properties_toolbarbutton;
80 private PropertyToolBarButton events_toolbarbutton;
81 private bool events_tab_visible;
83 private PropertyToolBar toolbar;
85 private PropertyGridView property_grid_view;
86 private Splitter splitter;
87 private Panel help_panel;
88 private Label help_title_label;
89 private Label help_description_label;
90 private MenuItem reset_menuitem;
91 private MenuItem description_menuitem;
93 private Color category_fore_color;
95 private Color commands_active_link_color;
96 private Color commands_disabled_link_color;
97 private Color commands_link_color;
99 #endregion // Private Members
102 public PropertyGrid ()
104 selected_objects = new object[0];
105 property_tabs = new PropertyTabCollection(this);
107 line_color = SystemColors.ScrollBar;
108 category_fore_color = line_color;
109 commands_visible_if_available = false;
110 property_sort = PropertySort.CategorizedAlphabetical;
111 property_grid_view = new PropertyGridView(this);
113 splitter = new Splitter();
114 splitter.Dock = DockStyle.Bottom;
116 help_panel = new Panel();
117 help_panel.Dock = DockStyle.Bottom;
118 //help_panel.DockPadding.All = 3;
119 help_panel.Height = 50;
120 help_panel.BackColor = SystemColors.Control;
123 help_title_label = new Label();
124 help_title_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
125 help_title_label.Name = "help_title_label";
126 help_title_label.Font = new Font(this.Font,FontStyle.Bold);
127 help_title_label.Location = new Point(2,2);
128 help_title_label.Height = 17;
129 help_title_label.Width = help_panel.Width - 4;
132 help_description_label = new Label();
133 help_description_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
134 help_description_label.AutoEllipsis = true;
135 help_description_label.AutoSize = false;
136 help_description_label.Font = this.Font;
137 help_description_label.Location = new Point(2,help_title_label.Top+help_title_label.Height);
138 help_description_label.Width = help_panel.Width - 4;
139 help_description_label.Height = help_panel.Height - help_description_label.Top - 2;
141 help_panel.Controls.Add(help_description_label);
142 help_panel.Controls.Add(help_title_label);
143 help_panel.Paint+=new PaintEventHandler(help_panel_Paint);
145 toolbar = new PropertyToolBar();
146 toolbar.Dock = DockStyle.Top;
147 categorized_toolbarbutton = new PropertyToolBarButton ();
148 categorized_toolbarbutton.Pushed = true;
149 alphabetic_toolbarbutton = new PropertyToolBarButton ();
150 propertypages_toolbarbutton = new PropertyToolBarButton ();
151 separator_toolbarbutton = new PropertyToolBarSeparator ();
152 ContextMenu context_menu = new ContextMenu();
154 categorized_image = new Bitmap (typeof (PropertyGrid), "propertygrid-categorized.png");
155 alphabetical_image = new Bitmap (typeof (PropertyGrid), "propertygrid-alphabetical.png");
156 propertypages_image = new Bitmap (typeof (PropertyGrid), "propertygrid-propertypages.png");
158 toolbar_imagelist = new ImageList();
159 toolbar_imagelist.ColorDepth = ColorDepth.Depth32Bit;
160 toolbar_imagelist.ImageSize = new System.Drawing.Size(16, 16);
161 toolbar_imagelist.TransparentColor = System.Drawing.Color.Transparent;
163 toolbar.Appearance = ToolBarAppearance.Flat;
164 toolbar.AutoSize = false;
166 toolbar.ImageList = toolbar_imagelist;
167 toolbar.Location = new System.Drawing.Point(0, 0);
168 toolbar.ShowToolTips = true;
169 toolbar.Size = new System.Drawing.Size(256, 27);
170 toolbar.TabIndex = 0;
172 toolbar.Items.AddRange (new ToolStripItem [] {categorized_toolbarbutton,
173 alphabetic_toolbarbutton,
174 new PropertyToolBarSeparator (),
175 propertypages_toolbarbutton});
176 //toolbar.ButtonSize = new System.Drawing.Size (20, 20);
177 toolbar.ItemClicked += new ToolStripItemClickedEventHandler (toolbar_ButtonClick);
179 toolbar.Buttons.AddRange(new ToolBarButton [] {categorized_toolbarbutton,
180 alphabetic_toolbarbutton,
181 new PropertyToolBarSeparator (),
182 propertypages_toolbarbutton});
183 toolbar.ButtonSize = new System.Drawing.Size(20, 20);
184 toolbar.ButtonClick += new ToolBarButtonClickEventHandler(toolbar_ButtonClick);
187 categorized_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
188 categorized_toolbarbutton.ToolTipText = Locale.GetText ("Categorized");
190 alphabetic_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
191 alphabetic_toolbarbutton.ToolTipText = Locale.GetText ("Alphabetic");
193 propertypages_toolbarbutton.Enabled = false;
194 propertypages_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
195 propertypages_toolbarbutton.ToolTipText = "Property Pages";
197 properties_tab = new PropertiesTab ();
198 selected_tab = properties_tab;
199 RefreshToolbar (property_tabs);
201 reset_menuitem = context_menu.MenuItems.Add("Reset");
202 reset_menuitem.Click +=new EventHandler(OnResetPropertyClick);
203 context_menu.MenuItems.Add("-");
204 description_menuitem = context_menu.MenuItems.Add("Description");
205 description_menuitem.Click += new EventHandler(OnDescriptionClick);
206 description_menuitem.Checked = this.HelpVisible;
207 this.ContextMenu = context_menu;
208 toolbar.ContextMenu = context_menu;
210 BorderHelperControl helper = new BorderHelperControl ();
211 helper.Dock = DockStyle.Fill;
212 helper.Controls.Add (property_grid_view);
214 this.Controls.Add(helper);
215 this.Controls.Add(toolbar);
216 this.Controls.Add(splitter);
217 this.Controls.Add(help_panel);
218 this.Name = "PropertyGrid";
219 this.Size = new System.Drawing.Size(256, 400);
221 #endregion // Constructors
223 #region Public Instance Properties
225 [BrowsableAttribute(false)]
226 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
227 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
228 public AttributeCollection BrowsableAttributes {
230 if (browsable_attributes == null) {
231 browsable_attributes = new AttributeCollection (new Attribute[] {
232 BrowsableAttribute.Yes });
234 return browsable_attributes;
237 if (browsable_attributes == value)
240 if (browsable_attributes == null || browsable_attributes.Count == 0)
241 browsable_attributes = null;
243 browsable_attributes = value;
248 [EditorBrowsable(EditorBrowsableState.Never)]
249 public override bool AutoScroll {
251 return base.AutoScroll;
254 base.AutoScroll = value;
258 public override Color BackColor {
260 return base.BackColor;
264 base.BackColor = value;
265 toolbar.BackColor = value;
271 [EditorBrowsable(EditorBrowsableState.Never)]
272 public override Image BackgroundImage {
274 return base.BackgroundImage;
277 base.BackgroundImage = value;
282 [EditorBrowsable(EditorBrowsableState.Never)]
284 public override ImageLayout BackgroundImageLayout {
285 get { return base.BackgroundImageLayout; }
286 set { base.BackgroundImageLayout = value; }
290 [BrowsableAttribute(false)]
291 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
292 public virtual bool CanShowCommands {
294 return can_show_commands;
298 [DefaultValue(typeof(Color), "ControlText")]
303 Color CategoryForeColor {
305 return category_fore_color;
308 if (category_fore_color != value) {
309 category_fore_color = value;
315 public Color CommandsBackColor {
317 return commands_back_color;
321 if (commands_back_color == value) {
324 commands_back_color = value;
328 public Color CommandsForeColor {
330 return commands_fore_color;
334 if (commands_fore_color == value) {
337 commands_fore_color = value;
341 public Color CommandsActiveLinkColor {
343 return commands_active_link_color;
346 commands_active_link_color = value;
350 public Color CommandsDisabledLinkColor {
352 return commands_disabled_link_color;
355 commands_disabled_link_color = value;
359 public Color CommandsLinkColor {
361 return commands_link_color;
364 commands_link_color = value;
369 [BrowsableAttribute (false)]
370 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
371 [MonoTODO ("Commands are not implemented yet.")]
372 public virtual bool CommandsVisible {
374 return commands_visible;
379 [DefaultValue (true)]
381 [DefaultValue (false)]
383 public virtual bool CommandsVisibleIfAvailable {
385 return commands_visible_if_available;
389 if (commands_visible_if_available == value) {
392 commands_visible_if_available = value;
396 [BrowsableAttribute(false)]
397 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
398 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
399 public Point ContextMenuDefaultLocation {
401 return context_menu_default_location;
406 [EditorBrowsable(EditorBrowsableState.Never)]
407 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
408 public new Control.ControlCollection Controls {
410 return base.Controls;
415 [EditorBrowsable(EditorBrowsableState.Never)]
416 public override Color ForeColor {
418 return base.ForeColor;
421 base.ForeColor = value;
426 [DefaultValue ("Color [Control]")]
428 public Color HelpBackColor {
430 return help_panel.BackColor;
433 if (help_panel.BackColor == value) {
437 help_panel.BackColor = value;
442 [DefaultValue ("Color [ControlText]")]
444 public Color HelpForeColor {
446 return help_panel.ForeColor;
450 if (help_panel.ForeColor == value) {
454 help_panel.ForeColor = value;
460 public virtual bool HelpVisible {
462 return help_panel.Visible;
466 if (help_panel.Visible == value) {
470 help_panel.Visible = value;
475 [DefaultValue (false)]
477 public bool LargeButtons {
479 return large_buttons;
483 if (large_buttons == value) {
487 large_buttons = value;
492 [DefaultValue ("Color [InactiveBorder]")]
494 public Color LineColor {
500 if (line_color == value) {
509 [EditorBrowsable(EditorBrowsableState.Never)]
511 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
512 public new Padding Padding {
513 get { return base.Padding; }
514 set { base.Padding = value; }
518 [DefaultValue(PropertySort.CategorizedAlphabetical)]
519 public PropertySort PropertySort {
521 return property_sort;
526 if (!Enum.IsDefined (typeof (PropertySort), value))
527 throw new InvalidEnumArgumentException ("value", (int) value, typeof (PropertySort));
529 if (property_sort == value)
532 // we do not need to update the the grid items and fire
533 // a PropertySortChanged event when switching between
534 // Categorized and CateogizedAlphabetical
535 bool needUpdate = (property_sort & PropertySort.Categorized) == 0 ||
536 (value & PropertySort.Categorized) == 0;
537 property_sort = value;
539 UpdateSortLayout (root_grid_item);
541 if (selected_grid_item != null) {
542 if (selected_grid_item.GridItemType == GridItemType.Category &&
543 (value == PropertySort.Alphabetical || value == PropertySort.NoSort))
544 SelectItemCore (null, null);
546 SelectItemCore (null, selected_grid_item);
548 property_grid_view.UpdateView ();
551 EventHandler eh = (EventHandler)(Events [PropertySortChangedEvent]);
553 eh (this, EventArgs.Empty);
559 [BrowsableAttribute(false)]
560 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
561 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
562 public PropertyTabCollection PropertyTabs {
563 get { return property_tabs; }
566 [BrowsableAttribute(false)]
567 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
568 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
569 public GridItem SelectedGridItem {
570 get { return selected_grid_item; }
573 throw new ArgumentException ("GridItem specified to PropertyGrid.SelectedGridItem must be a valid GridItem.");
574 if (value != selected_grid_item) {
575 GridEntry oldItem = selected_grid_item;
576 SelectItemCore (oldItem, (GridEntry)value);
577 OnSelectedGridItemChanged (new SelectedGridItemChangedEventArgs (oldItem, value));
582 internal GridItem RootGridItem {
583 get { return root_grid_item; }
586 private void UpdateHelp (GridItem item)
589 help_title_label.Text = string.Empty;
590 help_description_label.Text = string.Empty;
592 help_title_label.Text = item.Label;
593 if (item.PropertyDescriptor != null)
594 this.help_description_label.Text = item.PropertyDescriptor.Description;
598 private void SelectItemCore (GridEntry oldItem, GridEntry item)
601 selected_grid_item = item;
602 property_grid_view.SelectItem (oldItem, item);
605 internal void OnPropertyValueChangedInternal (GridItem item, object property_value)
607 PopulateSubGridItems (selected_grid_item);
608 property_grid_view.UpdateView ();
609 OnPropertyValueChanged (new PropertyValueChangedEventArgs (item, property_value));
612 internal void OnExpandItem (GridEntry item)
614 property_grid_view.ExpandItem (item);
617 internal void OnCollapseItem (GridEntry item)
619 property_grid_view.CollapseItem (item);
622 internal DialogResult ShowError (string text)
624 return this.ShowError (text, MessageBoxButtons.OK);
627 internal DialogResult ShowError (string text, MessageBoxButtons buttons)
630 throw new ArgumentNullException ("text");
631 return MessageBox.Show (this, text, "Properties Window", buttons, MessageBoxIcon.Exclamation);
635 [TypeConverter("System.Windows.Forms.PropertyGrid+SelectedObjectConverter, " + Consts.AssemblySystem_Windows_Forms)]
636 public object SelectedObject {
638 if (selected_objects.Length > 0)
639 return selected_objects[0];
644 if (selected_objects != null && selected_objects.Length == 1 && selected_objects[0] == value)
647 SelectedObjects = new object[0];
649 SelectedObjects = new object[] {value};
654 [BrowsableAttribute(false)]
655 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
656 public object[] SelectedObjects {
658 return selected_objects;
662 SelectItemCore (null, null); // unselect current item in the view
664 for (int i = 0; i < value.Length; i++) {
665 if (value [i] == null)
666 throw new ArgumentException (String.Format ("Item {0} in the objs array is null.", i));
668 selected_objects = value;
670 selected_objects = new object [0];
673 ShowEventsButton (false);
674 PopulateGrid (selected_objects);
675 RefreshTabs(PropertyTabScope.Component);
676 if (root_grid_item != null)
677 SelectItemCore (null, GetDefaultPropertyItem (root_grid_item, selected_tab));
678 property_grid_view.UpdateView ();
679 OnSelectedObjectsChanged (EventArgs.Empty);
683 [BrowsableAttribute(false)]
684 [EditorBrowsable(EditorBrowsableState.Advanced)]
685 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
686 public PropertyTab SelectedTab {
687 get { return selected_tab; }
690 public override ISite Site {
691 get { return base.Site; }
692 set { base.Site = value; }
697 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
698 public override string Text {
699 get { return base.Text; }
700 set { base.Text = value; }
705 public virtual bool ToolbarVisible {
706 get { return toolbar.Visible; }
708 if (toolbar.Visible == value) {
712 toolbar.Visible = value;
717 protected ToolStripRenderer ToolStripRenderer {
719 if (toolbar != null) {
720 return toolbar.Renderer;
725 if (toolbar != null) {
726 toolbar.Renderer = value;
734 [DefaultValue ("Color [Window]")]
736 public Color ViewBackColor {
737 get { return property_grid_view.BackColor; }
739 if (property_grid_view.BackColor == value) {
743 property_grid_view.BackColor = value;
748 [DefaultValue ("Color [WindowText]")]
750 public Color ViewForeColor {
751 get { return property_grid_view.ForeColor; }
753 if (property_grid_view.ForeColor == value) {
757 property_grid_view.ForeColor = value;
762 [DefaultValue (false)]
763 public bool UseCompatibleTextRendering {
764 get { return use_compatible_text_rendering; }
765 set { use_compatible_text_rendering = value; }
769 #endregion // Public Instance Properties
771 #region Protected Instance Properties
773 protected override Size DefaultSize {
774 get { return base.DefaultSize; }
779 [EditorBrowsable(EditorBrowsableState.Advanced)]
780 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
781 protected virtual Type DefaultTabType {
782 get { return typeof(PropertiesTab); }
785 protected bool DrawFlatToolbar {
786 get { return (toolbar.Appearance == ToolBarAppearance.Flat); }
789 toolbar.Appearance = ToolBarAppearance.Flat;
791 toolbar.Appearance = ToolBarAppearance.Normal;
795 protected internal override bool ShowFocusCues {
796 get { return base.ShowFocusCues; }
799 #endregion // Protected Instance Properties
801 #region Public Instance Methods
803 protected override void Dispose(bool disposing) {
804 base.Dispose(disposing);
807 public void CollapseAllGridItems ()
809 GridEntry category = FindCategoryItem (selected_grid_item);
810 if (category != null)
811 SelectedGridItem = category;
812 CollapseItemRecursive (root_grid_item);
813 property_grid_view.UpdateView ();
816 private void CollapseItemRecursive (GridItem item)
821 foreach (GridItem child in item.GridItems) {
822 CollapseItemRecursive (child);
823 if (child.Expandable)
824 child.Expanded = false;
828 private GridEntry FindCategoryItem (GridEntry entry)
830 if (entry == null || (property_sort != PropertySort.Categorized &&
831 property_sort != PropertySort.CategorizedAlphabetical))
834 if (entry.GridItemType == GridItemType.Category)
837 GridEntry category = null;
838 GridItem current = (GridItem)entry;
839 while (category == null) {
840 if (current.Parent != null && current.Parent.GridItemType == GridItemType.Category)
841 category = (GridEntry) current.Parent;
842 current = current.Parent;
846 return (GridEntry) category;
849 public void ExpandAllGridItems ()
851 ExpandItemRecursive (root_grid_item);
852 property_grid_view.UpdateView ();
855 private void ExpandItemRecursive (GridItem item)
860 foreach (GridItem child in item.GridItems) {
861 ExpandItemRecursive (child);
862 if (child.Expandable)
863 child.Expanded = true;
867 public override void Refresh ()
870 property_grid_view.UpdateView ();
873 private void toolbar_Clicked (PropertyToolBarButton button)
878 if (button == alphabetic_toolbarbutton) {
879 this.PropertySort = PropertySort.Alphabetical;
880 alphabetic_toolbarbutton.Pushed = true;
881 categorized_toolbarbutton.Pushed = false;
882 } else if (button == categorized_toolbarbutton) {
883 this.PropertySort = PropertySort.CategorizedAlphabetical;
884 categorized_toolbarbutton.Pushed = true;
885 alphabetic_toolbarbutton.Pushed = false;
888 SelectPropertyTab (button.PropertyTab);
892 private void SelectPropertyTab (PropertyTab propertyTab)
894 if (propertyTab != null && selected_tab != propertyTab) {
895 foreach (object toolbarItem in toolbar.Items) {
896 PropertyToolBarButton button = toolbarItem as PropertyToolBarButton;
897 if (button != null && button.PropertyTab != null) {
898 if (button.PropertyTab == selected_tab)
899 button.Pushed = false;
900 else if (button.PropertyTab == propertyTab)
901 button.Pushed = true;
904 selected_tab = propertyTab;
905 PopulateGrid (selected_objects);
906 SelectItemCore (null, GetDefaultPropertyItem (root_grid_item, selected_tab));
910 protected void ShowEventsButton (bool value)
912 if (value && property_tabs.Contains (typeof (EventsTab)))
913 events_tab_visible = true;
915 events_tab_visible = false;
916 RefreshTabs (PropertyTabScope.Component);
919 public void RefreshTabs (PropertyTabScope tabScope)
921 property_tabs.Clear (tabScope);
922 if (selected_objects != null) {
923 Type[] tabTypes = null;
924 PropertyTabScope[] tabScopes = null;
926 if (events_tab_visible && property_tabs.Contains (typeof (EventsTab)))
927 property_tabs.InsertTab (0, properties_tab, PropertyTabScope.Component);
929 GetMergedPropertyTabs (selected_objects, out tabTypes, out tabScopes);
930 if (tabTypes != null && tabScopes != null && tabTypes.Length > 0) {
931 bool selectedTabPreserved = false;
932 for (int i=0; i < tabTypes.Length; i++) {
933 property_tabs.AddTabType (tabTypes[i], tabScopes[i]);
934 if (tabTypes[i] == selected_tab.GetType ())
935 selectedTabPreserved = true;
937 if (!selectedTabPreserved)
938 SelectPropertyTab (properties_tab);
941 SelectPropertyTab (properties_tab);
943 RefreshToolbar (property_tabs);
946 private void RefreshToolbar (PropertyTabCollection tabs)
948 EnsurePropertiesTab ();
950 toolbar.SuspendLayout ();
951 toolbar.Items.Clear ();
952 toolbar_imagelist.Images.Clear ();
955 toolbar.Items.Add (categorized_toolbarbutton);
956 toolbar_imagelist.Images.Add (categorized_image);
957 categorized_toolbarbutton.ImageIndex = imageIndex;
959 toolbar.Items.Add (alphabetic_toolbarbutton);
960 toolbar_imagelist.Images.Add (alphabetical_image);
961 alphabetic_toolbarbutton.ImageIndex = imageIndex;
963 toolbar.Items.Add (separator_toolbarbutton);
964 if (tabs != null && tabs.Count > 0) {
965 foreach (PropertyTab tab in tabs) {
966 PropertyToolBarButton button = new PropertyToolBarButton (tab);
967 toolbar.Items.Add (button);
968 if (tab.Bitmap != null) {
969 tab.Bitmap.MakeTransparent ();
970 toolbar_imagelist.Images.Add (tab.Bitmap);
971 button.ImageIndex = imageIndex;
974 if (tab == selected_tab)
975 button.Pushed = true;
977 toolbar.Items.Add (new PropertyToolBarSeparator ());
980 toolbar.Items.Add (propertypages_toolbarbutton);
981 toolbar_imagelist.Images.Add (propertypages_image);
982 propertypages_toolbarbutton.ImageIndex = imageIndex;
984 toolbar.ResumeLayout ();
987 private void EnsurePropertiesTab ()
989 if (property_tabs == null)
992 if (property_tabs.Count > 0 && !property_tabs.Contains (typeof (PropertiesTab)))
993 property_tabs.InsertTab (0, properties_tab, PropertyTabScope.Component);
996 private void GetMergedPropertyTabs (object[] objects, out Type[] tabTypes, out PropertyTabScope[] tabScopes)
1000 if (objects == null || objects.Length == 0)
1003 ArrayList intersection = null;
1004 ArrayList scopes = new ArrayList ();
1005 for (int i=0; i < objects.Length; i++) {
1006 if (objects[i] == null)
1008 PropertyTabAttribute tabAttribute = (PropertyTabAttribute)TypeDescriptor.GetAttributes (objects[i])[typeof (PropertyTabAttribute)];
1009 if (tabAttribute == null || tabAttribute.TabClasses == null || tabAttribute.TabClasses.Length == 0)
1012 ArrayList new_intersection = new ArrayList ();
1014 IList currentIntersection = (i == 0 ? (IList)tabAttribute.TabClasses : (IList)intersection);
1015 for (int j=0; j < currentIntersection.Count; j++) {
1016 if ((Type)intersection[j] == tabAttribute.TabClasses[j]) {
1017 new_intersection.Add (tabAttribute.TabClasses[j]);
1018 scopes.Add (tabAttribute.TabScopes[j]);
1021 intersection = new_intersection;
1024 tabTypes = new Type[intersection.Count];
1025 intersection.CopyTo (tabTypes);
1026 tabScopes = new PropertyTabScope[tabTypes.Length];
1027 scopes.CopyTo (tabScopes);
1030 public void ResetSelectedProperty()
1032 if (selected_grid_item == null)
1034 selected_grid_item.ResetValue ();
1036 #endregion // Public Instance Methods
1038 #region Protected Instance Methods
1040 protected virtual PropertyTab CreatePropertyTab (Type tabType)
1042 if (!typeof(PropertyTab).IsAssignableFrom (tabType))
1045 PropertyTab tab = null;
1047 ConstructorInfo ctor = tabType.GetConstructor (new Type[] { typeof (IServiceProvider) });
1049 tab = (PropertyTab)ctor.Invoke (new object[] { this.Site });
1051 tab = (PropertyTab)Activator.CreateInstance (tabType);
1056 protected void OnComComponentNameChanged(ComponentRenameEventArgs e)
1058 ComponentRenameEventHandler eh = (ComponentRenameEventHandler)(Events [ComComponentNameChangedEvent]);
1064 protected override void OnEnabledChanged (EventArgs e) {
1065 base.OnEnabledChanged (e);
1070 protected override void OnFontChanged(EventArgs e) {
1071 base.OnFontChanged (e);
1074 protected override void OnGotFocus(EventArgs e) {
1078 protected override void OnHandleCreated (EventArgs e) {
1079 base.OnHandleCreated (e);
1082 protected override void OnHandleDestroyed (EventArgs e) {
1083 base.OnHandleDestroyed (e);
1086 protected override void OnMouseDown (MouseEventArgs me) {
1087 base.OnMouseDown (me);
1090 protected override void OnMouseMove (MouseEventArgs me) {
1091 base.OnMouseMove (me);
1094 protected override void OnMouseUp (MouseEventArgs me) {
1095 base.OnMouseUp (me);
1098 protected void OnNotifyPropertyValueUIItemsChanged(object sender, EventArgs e)
1100 property_grid_view.UpdateView ();
1103 protected override void OnPaint (PaintEventArgs pevent) {
1104 pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
1105 base.OnPaint (pevent);
1109 protected virtual void OnPropertySortChanged(EventArgs e) {
1110 EventHandler eh = (EventHandler) Events [PropertySortChangedEvent];
1116 protected virtual void OnPropertyTabChanged (PropertyTabChangedEventArgs e)
1118 PropertyTabChangedEventHandler eh = (PropertyTabChangedEventHandler)(Events [PropertyTabChangedEvent]);
1123 protected virtual void OnPropertyValueChanged (PropertyValueChangedEventArgs e) {
1124 PropertyValueChangedEventHandler eh = (PropertyValueChangedEventHandler)(Events [PropertyValueChangedEvent]);
1129 protected override void OnResize (EventArgs e) {
1133 protected virtual void OnSelectedGridItemChanged (SelectedGridItemChangedEventArgs e) {
1134 SelectedGridItemChangedEventHandler eh = (SelectedGridItemChangedEventHandler)(Events [SelectedGridItemChangedEvent]);
1139 protected virtual void OnSelectedObjectsChanged (EventArgs e) {
1140 EventHandler eh = (EventHandler)(Events [SelectedObjectsChangedEvent]);
1145 protected override void OnSystemColorsChanged (EventArgs e) {
1146 base.OnSystemColorsChanged (e);
1149 protected override void OnVisibleChanged (EventArgs e) {
1150 base.OnVisibleChanged (e);
1153 protected override bool ProcessDialogKey (Keys keyData) {
1154 return base.ProcessDialogKey (keyData);
1158 [EditorBrowsable (EditorBrowsableState.Never)]
1160 protected override void ScaleCore (float dx, float dy) {
1161 base.ScaleCore (dx, dy);
1164 protected override void WndProc (ref Message m)
1166 base.WndProc (ref m);
1171 static object PropertySortChangedEvent = new object ();
1172 static object PropertyTabChangedEvent = new object ();
1173 static object PropertyValueChangedEvent = new object ();
1174 static object SelectedGridItemChangedEvent = new object ();
1175 static object SelectedObjectsChangedEvent = new object ();
1177 public event EventHandler PropertySortChanged {
1178 add { Events.AddHandler (PropertySortChangedEvent, value); }
1179 remove { Events.RemoveHandler (PropertySortChangedEvent, value); }
1182 public event PropertyTabChangedEventHandler PropertyTabChanged {
1183 add { Events.AddHandler (PropertyTabChangedEvent, value); }
1184 remove { Events.RemoveHandler (PropertyTabChangedEvent, value); }
1187 public event PropertyValueChangedEventHandler PropertyValueChanged {
1188 add { Events.AddHandler (PropertyValueChangedEvent, value); }
1189 remove { Events.RemoveHandler (PropertyValueChangedEvent, value); }
1192 public event SelectedGridItemChangedEventHandler SelectedGridItemChanged {
1193 add { Events.AddHandler (SelectedGridItemChangedEvent, value); }
1194 remove { Events.RemoveHandler (SelectedGridItemChangedEvent, value); }
1197 public event EventHandler SelectedObjectsChanged {
1198 add { Events.AddHandler (SelectedObjectsChangedEvent, value); }
1199 remove { Events.RemoveHandler (SelectedObjectsChangedEvent, value); }
1203 [EditorBrowsable(EditorBrowsableState.Never)]
1204 public new event EventHandler BackgroundImageChanged {
1205 add { base.BackgroundImageChanged += value; }
1206 remove { base.BackgroundImageChanged -= value; }
1211 [EditorBrowsable(EditorBrowsableState.Never)]
1212 public new event EventHandler BackgroundImageLayoutChanged {
1213 add { base.BackgroundImageLayoutChanged += value; }
1214 remove { base.BackgroundImageLayoutChanged -= value; }
1219 [EditorBrowsable(EditorBrowsableState.Never)]
1220 public new event EventHandler ForeColorChanged {
1221 add { base.ForeColorChanged += value; }
1222 remove { base.ForeColorChanged -= value; }
1225 [EditorBrowsable(EditorBrowsableState.Advanced)]
1227 public new event KeyEventHandler KeyDown {
1228 add { base.KeyDown += value; }
1229 remove { base.KeyDown -= value; }
1233 [EditorBrowsable(EditorBrowsableState.Advanced)]
1234 public new event KeyPressEventHandler KeyPress {
1235 add { base.KeyPress += value; }
1236 remove { base.KeyPress -= value; }
1239 [EditorBrowsable(EditorBrowsableState.Advanced)]
1241 public new event KeyEventHandler KeyUp {
1242 add { base.KeyUp += value; }
1243 remove { base.KeyUp -= value; }
1247 [EditorBrowsable(EditorBrowsableState.Advanced)]
1248 public new event MouseEventHandler MouseDown {
1249 add { base.MouseDown += value; }
1250 remove { base.MouseDown -= value; }
1253 [EditorBrowsable(EditorBrowsableState.Advanced)]
1255 public new event EventHandler MouseEnter {
1256 add { base.MouseEnter += value; }
1257 remove { base.MouseEnter -= value; }
1260 [EditorBrowsable(EditorBrowsableState.Advanced)]
1262 public new event EventHandler MouseLeave {
1263 add { base.MouseLeave += value; }
1264 remove { base.MouseLeave -= value; }
1267 [EditorBrowsable(EditorBrowsableState.Advanced)]
1269 public new event MouseEventHandler MouseMove {
1270 add { base.MouseMove += value; }
1271 remove { base.MouseMove -= value; }
1274 [EditorBrowsable(EditorBrowsableState.Advanced)]
1276 public new event MouseEventHandler MouseUp {
1277 add { base.MouseUp += value; }
1278 remove { base.MouseUp -= value; }
1282 [EditorBrowsable(EditorBrowsableState.Never)]
1283 public new event EventHandler PaddingChanged {
1284 add { base.PaddingChanged += value; }
1285 remove { base.PaddingChanged -= value; }
1289 public new event EventHandler TextChanged {
1290 add { base.TextChanged += value; }
1291 remove { base.TextChanged -= value; }
1296 #region Com2Interop.IComPropertyBrowser Interface
1298 bool ComponentModel.Com2Interop.IComPropertyBrowser.InPropertySet {
1300 throw new NotImplementedException();
1305 void ComponentModel.Com2Interop.IComPropertyBrowser.DropDownDone() {
1306 throw new NotImplementedException();
1310 bool ComponentModel.Com2Interop.IComPropertyBrowser.EnsurePendingChangesCommitted() {
1311 throw new NotImplementedException();
1315 void ComponentModel.Com2Interop.IComPropertyBrowser.HandleF4() {
1316 throw new NotImplementedException();
1320 void ComponentModel.Com2Interop.IComPropertyBrowser.LoadState(Microsoft.Win32.RegistryKey key) {
1321 throw new NotImplementedException();
1325 void ComponentModel.Com2Interop.IComPropertyBrowser.SaveState(Microsoft.Win32.RegistryKey key) {
1326 throw new NotImplementedException();
1329 static object ComComponentNameChangedEvent = new object ();
1330 event ComponentRenameEventHandler ComponentModel.Com2Interop.IComPropertyBrowser.ComComponentNameChanged {
1331 add { Events.AddHandler (ComComponentNameChangedEvent, value); }
1332 remove { Events.RemoveHandler (ComComponentNameChangedEvent, value); }
1334 #endregion // Com2Interop.IComPropertyBrowser Interface
1336 #region PropertyTabCollection Class
1337 public class PropertyTabCollection : ICollection, IEnumerable
1339 ArrayList property_tabs;
1340 ArrayList property_tabs_scopes;
1341 PropertyGrid property_grid;
1343 internal PropertyTabCollection (PropertyGrid propertyGrid)
1345 property_grid = propertyGrid;
1346 property_tabs = new ArrayList ();
1347 property_tabs_scopes = new ArrayList ();
1350 public PropertyTab this[int index] {
1351 get { return (PropertyTab)property_tabs[index]; }
1354 bool ICollection.IsSynchronized {
1355 get { return property_tabs.IsSynchronized; }
1358 void ICollection.CopyTo (Array array, int index)
1360 property_tabs.CopyTo (array, index);
1363 object ICollection.SyncRoot {
1364 get { return property_tabs.SyncRoot; }
1367 public IEnumerator GetEnumerator ()
1369 return property_tabs.GetEnumerator ();
1373 get { return property_tabs.Count; }
1376 public void AddTabType (Type propertyTabType)
1378 AddTabType (propertyTabType, PropertyTabScope.Global);
1381 public void AddTabType (Type propertyTabType, PropertyTabScope tabScope)
1383 if (propertyTabType == null)
1384 throw new ArgumentNullException ("propertyTabType");
1387 if (this.Contains (propertyTabType))
1389 PropertyTab tab = property_grid.CreatePropertyTab (propertyTabType);
1391 property_tabs.Add (tab);
1392 property_tabs_scopes.Add (tabScope);
1394 property_grid.RefreshToolbar (this);
1397 internal PropertyTabScope GetTabScope (PropertyTab tab)
1400 throw new ArgumentNullException ("tab");
1402 int index = property_tabs.IndexOf (tab);
1404 return (PropertyTabScope)property_tabs_scopes[index];
1405 return PropertyTabScope.Global;
1408 internal void InsertTab (int index, PropertyTab propertyTab, PropertyTabScope tabScope)
1410 if (propertyTab == null)
1411 throw new ArgumentNullException ("propertyTab");
1413 if (!this.Contains (propertyTab.GetType ())) {
1414 property_tabs.Insert (index, propertyTab);
1415 property_tabs_scopes.Insert (index, tabScope);
1419 internal bool Contains (Type propertyType)
1421 if (propertyType == null)
1422 throw new ArgumentNullException ("propertyType");
1424 foreach (PropertyTab t in property_tabs) {
1425 if (t.GetType () == propertyType)
1431 internal PropertyTab this[Type tabType] {
1433 foreach (PropertyTab tab in property_tabs) {
1434 if (tabType == tab.GetType ())
1441 public void Clear (PropertyTabScope tabScope)
1443 ArrayList toRemove = new ArrayList ();
1444 for (int i=0; i < property_tabs_scopes.Count; i++) {
1445 if ((PropertyTabScope)property_tabs_scopes[i] == tabScope)
1448 foreach (int indexToRemove in toRemove) {
1449 property_tabs.RemoveAt (indexToRemove);
1450 property_tabs_scopes.RemoveAt (indexToRemove);
1452 property_grid.RefreshToolbar (this);
1455 public void RemoveTabType (Type propertyTabType)
1457 if (propertyTabType == null)
1458 throw new ArgumentNullException ("propertyTabType");
1460 ArrayList toRemove = new ArrayList ();
1461 for (int i=0; i < property_tabs.Count; i++) {
1462 if (property_tabs[i].GetType () == propertyTabType)
1465 foreach (int indexToRemove in toRemove) {
1466 property_tabs.RemoveAt (indexToRemove);
1467 property_tabs_scopes.RemoveAt (indexToRemove);
1469 property_grid.RefreshToolbar (this);
1472 #endregion // PropertyTabCollection Class
1474 #region Private Helper Methods
1476 private GridItem FindFirstPropertyItem (GridItem root)
1478 if (root.GridItemType == GridItemType.Property)
1481 foreach (GridItem item in root.GridItems) {
1482 GridItem subitem = FindFirstPropertyItem (item);
1483 if (subitem != null)
1490 private GridEntry GetDefaultPropertyItem (GridEntry rootItem, PropertyTab propertyTab)
1492 if (rootItem == null || rootItem.GridItems.Count == 0 || propertyTab == null)
1494 object[] propertyOwners = rootItem.Values;
1495 if (propertyOwners == null || propertyOwners.Length == 0 || propertyOwners[0] == null)
1498 GridItem defaultSelected = null;
1499 if (propertyOwners.Length > 1)
1500 defaultSelected = rootItem.GridItems[0];
1502 PropertyDescriptor defaultProperty = propertyTab.GetDefaultProperty (propertyOwners[0]);
1503 if (defaultProperty != null)
1504 defaultSelected = FindItem (defaultProperty.Name, rootItem);
1505 if (defaultSelected == null)
1506 defaultSelected = FindFirstPropertyItem (rootItem);
1509 return defaultSelected as GridEntry;
1512 private GridEntry FindItem (string name, GridEntry rootItem)
1514 if (rootItem == null || name == null)
1517 if (property_sort == PropertySort.Alphabetical || property_sort == PropertySort.NoSort) {
1518 foreach (GridItem item in rootItem.GridItems) {
1519 if (item.Label == name) {
1520 return (GridEntry)item;
1523 } else if (property_sort == PropertySort.Categorized ||
1524 property_sort == PropertySort.CategorizedAlphabetical) {
1525 foreach (GridItem categoryItem in rootItem.GridItems) {
1526 foreach (GridItem item in categoryItem.GridItems) {
1527 if (item.Label == name) {
1528 return (GridEntry)item;
1538 private void toolbar_ButtonClick (object sender, ToolStripItemClickedEventArgs e)
1540 toolbar_Clicked (e.ClickedItem as PropertyToolBarButton);
1543 private void toolbar_ButtonClick (object sender, ToolBarButtonClickEventArgs e)
1545 toolbar_Clicked (e.Button as PropertyToolBarButton);
1549 private void OnResetPropertyClick (object sender, EventArgs e)
1551 ResetSelectedProperty();
1554 private void OnDescriptionClick (object sender, EventArgs e)
1556 this.HelpVisible = !this.HelpVisible;
1557 description_menuitem.Checked = this.HelpVisible;
1560 private void PopulateGrid (object[] objects)
1562 if (objects.Length > 0) {
1563 root_grid_item = new RootGridEntry (this, objects);
1564 PopulateRootGridItems (root_grid_item, objects, GetMergedPropertyNames (objects));
1566 root_grid_item = null;
1570 private bool IsPropertyVisible (PropertyDescriptor property, bool merging)
1572 if (property == null)
1576 MergablePropertyAttribute attrib = property.Attributes [typeof (MergablePropertyAttribute)] as MergablePropertyAttribute;
1577 if (attrib != null && !attrib.AllowMerge)
1584 private string[] GetMergedPropertyNames (object [] objects)
1586 ArrayList intersection = null;
1587 for (int i = 0; i < objects.Length; i ++) {
1588 if (objects [i] == null)
1591 PropertyDescriptorCollection properties = GetProperties (objects[i], BrowsableAttributes);
1592 ArrayList new_intersection = new ArrayList ();
1594 foreach (PropertyDescriptor currentProperty in (i == 0 ? (ICollection)properties : (ICollection)intersection)) {
1595 PropertyDescriptor matchingProperty = (i == 0 ? currentProperty : properties [currentProperty.Name]);
1597 if (!IsPropertyVisible (matchingProperty, objects.Length > 1))
1599 if (matchingProperty.PropertyType == currentProperty.PropertyType)
1600 new_intersection.Add (matchingProperty);
1603 intersection = new_intersection;
1606 string[] propertyNames = new string [intersection.Count];
1607 for (int i=0; i < intersection.Count; i++)
1608 propertyNames[i] = ((PropertyDescriptor)intersection[i]).Name;
1610 return propertyNames;
1613 private PropertyDescriptor GetPropertyDescriptor (object propertyOwner, string propertyName)
1615 if (propertyOwner == null || propertyName == null)
1618 PropertyDescriptorCollection properties = GetProperties (propertyOwner, BrowsableAttributes);
1619 if (properties != null)
1620 return properties[propertyName];
1624 private PropertyDescriptorCollection GetProperties (object propertyOwner, AttributeCollection attributes)
1626 if (propertyOwner == null || selected_tab == null)
1627 return new PropertyDescriptorCollection (null);
1629 Attribute[] atts = new Attribute[attributes.Count];
1630 attributes.CopyTo (atts, 0);
1631 return selected_tab.GetProperties (propertyOwner, atts);
1634 private void PopulateRootGridItems (GridEntry rootItem, object[] propertyOwners, string[] propertyNames)
1636 if (propertyOwners == null || propertyNames == null)
1639 bool categorized = property_sort == PropertySort.Categorized ||
1640 property_sort == PropertySort.CategorizedAlphabetical;
1641 rootItem.GridItems.Clear ();
1643 foreach (string propertyName in propertyNames) {
1644 GridEntry item = null;
1645 PropertyDescriptor[] properties = new PropertyDescriptor[propertyOwners.Length];
1646 for (int i=0; i < propertyOwners.Length; i++)
1647 properties[i] = GetPropertyDescriptor (propertyOwners[i], propertyName);
1650 string categoryName = null;
1651 foreach (PropertyDescriptor property in properties) {
1652 categoryName = property.Category;
1653 if (categoryName != null)
1656 if (categoryName == null)
1657 categoryName = UNCATEGORIZED_CATEGORY_LABEL;
1658 GridEntry category = (GridEntry)root_grid_item.GridItems[categoryName];
1659 if (category == null) {
1660 category = new CategoryGridEntry (this, categoryName, rootItem);
1661 category.Expanded = true;
1662 rootItem.GridItems.Add (category);
1664 item = new GridEntry (this, properties, category);
1665 category.GridItems.Add (item);
1667 item = new GridEntry (this, properties, rootItem);
1668 rootItem.GridItems.Add (item);
1671 PopulateSubGridItems (item);
1675 private void PopulateSubGridItems (GridEntry parentItem)
1677 parentItem.GridItems.Clear ();
1678 if (!IsExpandable (parentItem))
1681 object[] propertyOwners = parentItem.Values;
1682 if (propertyOwners == null)
1685 PropertyDescriptorCollection propertiesCollection = GetProperties (propertyOwners[0], BrowsableAttributes);
1686 if (propertiesCollection == null)
1689 foreach (PropertyDescriptor property in propertiesCollection) {
1690 string propertyName = property.Name;
1692 PropertyDescriptor[] properties = new PropertyDescriptor[propertyOwners.Length];
1693 for (int i=0; i < propertyOwners.Length; i++)
1694 properties[i] = GetPropertyDescriptor (propertyOwners[i], propertyName);
1696 GridEntry item = new GridEntry (this, properties, parentItem);
1697 parentItem.GridItems.Add (item);
1698 if (IsExpandable (item))
1699 PopulateSubGridItems (item);
1703 private bool IsExpandable (GridEntry item)
1705 if (item == null || item.PropertyDescriptor == null ||
1706 item.PropertyDescriptor.Converter == null)
1708 else if (!item.PropertyDescriptor.Converter.GetPropertiesSupported () &&
1709 !item.PropertyDescriptor.Attributes.Contains (
1710 DesignerSerializationVisibilityAttribute.Content))
1715 private void UpdateSortLayout (GridEntry rootItem)
1717 if (rootItem == null)
1720 GridItemCollection reordered = new GridItemCollection ();
1722 if (property_sort == PropertySort.Alphabetical || property_sort == PropertySort.NoSort) {
1723 alphabetic_toolbarbutton.Pushed = true;
1724 categorized_toolbarbutton.Pushed = false;
1725 foreach (GridItem item in rootItem.GridItems) {
1726 if (item.GridItemType == GridItemType.Category) {
1727 foreach (GridItem categoryChild in item.GridItems) {
1728 reordered.Add (categoryChild);
1729 ((GridEntry)categoryChild).SetParent (rootItem);
1732 reordered.Add (item);
1735 } else if (property_sort == PropertySort.Categorized ||
1736 property_sort == PropertySort.CategorizedAlphabetical) {
1737 alphabetic_toolbarbutton.Pushed = false;
1738 categorized_toolbarbutton.Pushed = true;
1739 GridItemCollection categories = new GridItemCollection ();
1741 foreach (GridItem item in rootItem.GridItems) {
1742 if (item.GridItemType == GridItemType.Category) {
1743 categories.Add (item);
1747 string categoryName = item.PropertyDescriptor.Category;
1748 if (categoryName == null)
1749 categoryName = UNCATEGORIZED_CATEGORY_LABEL;
1750 GridItem category_item = rootItem.GridItems [categoryName];
1751 if (category_item == null)
1752 category_item = categories [categoryName];
1754 if (category_item == null) {
1755 // Create category grid items if they already don't
1756 category_item = new CategoryGridEntry (this, categoryName, rootItem);
1757 category_item.Expanded = true;
1758 categories.Add (category_item);
1761 category_item.GridItems.Add (item);
1762 ((GridEntry)item).SetParent (category_item);
1765 reordered.AddRange (categories);
1768 rootItem.GridItems.Clear ();
1769 rootItem.GridItems.AddRange (reordered);
1772 private void help_panel_Paint(object sender, PaintEventArgs e) {
1773 e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(help_panel.BackColor), help_panel.ClientRectangle );
1774 e.Graphics.DrawRectangle(SystemPens.ControlDark, 0,0,help_panel.Width-1,help_panel.Height-1 );
1777 #endregion // Private Helper Methods
1779 #region Internal helper classes
1780 // as we can not change the color for BorderStyle.FixedSingle and we need the correct
1781 // ClientRectangle so that the ScrollBar doesn't draw over the border we need this class
1782 internal class BorderHelperControl : Control {
1784 public BorderHelperControl ()
1786 BackColor = ThemeEngine.Current.ColorWindow;
1789 protected override void OnPaint (PaintEventArgs e)
1791 e.Graphics.DrawRectangle (SystemPens.ControlDark, 0 , 0 , Width - 1, Height - 1);
1795 protected override void OnSizeChanged (EventArgs e)
1797 if (Controls.Count == 1) {
1798 Control control = Controls [0];
1800 if (control.Location.X != 1 || control.Location.Y != 1)
1801 control.Location = new Point (1, 1);
1803 control.Width = ClientRectangle.Width - 2;
1804 control.Height = ClientRectangle.Height - 2;
1806 base.OnSizeChanged (e);
1810 private class PropertyToolBarSeparator :
1817 public PropertyToolBarSeparator ()
1820 this.Style = ToolBarButtonStyle.Separator;
1825 private class PropertyToolBarButton :
1832 private PropertyTab property_tab;
1834 public PropertyToolBarButton ()
1838 public PropertyToolBarButton (PropertyTab propertyTab)
1840 if (propertyTab == null)
1841 throw new ArgumentNullException ("propertyTab");
1842 property_tab = propertyTab;
1845 public PropertyTab PropertyTab {
1846 get { return property_tab; }
1850 public bool Pushed {
1851 get { return base.Checked; }
1852 set { base.Checked = value; }
1855 public ToolBarButtonStyle Style {
1856 get { return ToolBarButtonStyle.PushButton; }
1862 // needed! this little helper makes it possible to draw a different toolbar border
1863 // and toolbar backcolor in ThemeWin32Classic
1864 internal class PropertyToolBar :
1875 public PropertyToolBar ()
1877 SetStyle (ControlStyles.ResizeRedraw, true);
1879 GripStyle = ToolStripGripStyle.Hidden;
1884 public IList Items {
1885 get { return base.Buttons; }
1890 public bool ShowToolTips {
1891 get { return base.ShowItemToolTips; }
1892 set { base.ShowItemToolTips = value; }
1895 public ToolBarAppearance Appearance {
1896 get { return flat ? ToolBarAppearance.Flat : ToolBarAppearance.Normal; }
1898 if (value == Appearance)
1902 case ToolBarAppearance.Flat:
1903 Renderer = new ToolStripSystemRenderer ();
1905 case ToolBarAppearance.Normal:
1906 ProfessionalColorTable table = new ProfessionalColorTable ();
1907 table.UseSystemColors = true;
1908 Renderer = new ToolStripProfessionalRenderer (table);
1917 [MonoTODO ("not sure what this class does, but it's listed as a type converter for a property in this class, and this causes problems if it's not present")]
1918 private class SelectedObjectConverter : TypeConverter