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-2005 Novell, Inc.
23 // Jonathan Chambers (jonathan.chambers@ansys.com)
30 using System.Drawing.Design;
31 using System.ComponentModel;
32 using System.Collections;
33 using System.ComponentModel.Design;
34 using System.Reflection;
35 using System.Windows.Forms.Design;
36 using System.Windows.Forms.PropertyGridInternal;
38 namespace System.Windows.Forms {
39 [Designer("System.Windows.Forms.Design.PropertyGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
40 public class PropertyGrid : System.Windows.Forms.ContainerControl, ComponentModel.Com2Interop.IComPropertyBrowser {
41 #region Private Members
44 private const int GRID_ITEM_HEIGHT = 16;
45 private const int GRID_LEFT_COLUMN_WIDTH = 16;
46 private const int DIVIDER_PADDING = 2;
48 private AttributeCollection browsable_attributes = null;
49 private bool can_show_commands = false;
50 private Color commands_back_color;
51 private Color commands_fore_color;
52 private bool commands_visible;
53 private bool commands_visible_if_available;
54 private Point context_menu_default_location;
55 private bool large_buttons;
56 private Color line_color;
57 private PropertySort property_sort;
58 private PropertyTabCollection property_tabs;
59 private GridItem selected_grid_item;
60 internal GridItem root_grid_item;
61 private object[] selected_objects;
62 private PropertyTab selected_tab;
64 private ImageList toolbar_imagelist;
65 private ToolBarButton categorized_toolbarbutton;
66 private ToolBarButton alphabetic_toolbarbutton;
67 private ToolBarButton separator_toolbarbutton;
68 private ToolBarButton propertypages_toolbarbutton;
70 internal ToolBar toolbar;
71 internal PropertyGridView property_grid_view;
72 internal Splitter splitter;
73 internal Panel help_panel;
74 internal Label help_title_label;
75 internal Label help_description_label;
76 private ContextMenu context_menu;
77 private MenuItem reset_menuitem;
78 private MenuItem description_menuitem;
79 private object current_property_value;
81 #endregion // Private Members
84 public PropertyGrid() {
85 selected_objects = new object[0];
86 property_tabs = new PropertyTabCollection();
88 line_color = SystemColors.ScrollBar;
89 line_color = SystemColors.ScrollBar;
90 browsable_attributes = new AttributeCollection(new Attribute[] {});
91 commands_visible_if_available = false;
92 property_sort = PropertySort.Categorized;
94 property_grid_view = new PropertyGridView(this);
96 splitter = new Splitter();
97 splitter.Dock = DockStyle.Bottom;
99 help_panel = new Panel();
100 help_panel.Dock = DockStyle.Bottom;
101 //help_panel.DockPadding.All = 3;
102 help_panel.Height = 50;
103 help_panel.BackColor = SystemColors.Control;
106 help_title_label = new Label();
107 help_title_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
108 help_title_label.Name = "help_title_label";
109 help_title_label.Font = new Font(this.Font,FontStyle.Bold);
110 help_title_label.Location = new Point(2,2);
111 help_title_label.Height = 17;
112 help_title_label.Width = help_panel.Width - 4;
115 help_description_label = new Label();
116 help_description_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
117 help_description_label.Name = "help_description_label";
118 help_description_label.Font = this.Font;
119 help_description_label.Location = new Point(2,help_title_label.Top+help_title_label.Height);
120 help_description_label.Width = help_panel.Width - 4;
121 help_description_label.Height = help_panel.Height - help_description_label.Top - 2;
123 help_panel.Controls.Add(help_description_label);
124 help_panel.Controls.Add(help_title_label);
125 help_panel.Paint+=new PaintEventHandler(help_panel_Paint);
127 toolbar = new PropertyToolBar();
128 toolbar.Dock = DockStyle.Top;
129 categorized_toolbarbutton = new ToolBarButton();
130 alphabetic_toolbarbutton = new ToolBarButton();
131 separator_toolbarbutton = new ToolBarButton();
132 propertypages_toolbarbutton = new ToolBarButton();
133 context_menu = new ContextMenu();
135 toolbar_imagelist = new ImageList();
136 toolbar_imagelist.ColorDepth = ColorDepth.Depth32Bit;
137 toolbar_imagelist.ImageSize = new System.Drawing.Size(16, 16);
138 toolbar_imagelist.TransparentColor = System.Drawing.Color.Transparent;
139 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_category") );
140 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_alphabetical") );
141 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_tab_properties") );
143 toolbar.Appearance = ToolBarAppearance.Flat;
144 toolbar.AutoSize = false;
145 toolbar.Buttons.AddRange(new ToolBarButton[] {categorized_toolbarbutton,
146 alphabetic_toolbarbutton,
147 separator_toolbarbutton,
148 propertypages_toolbarbutton});
150 toolbar.ButtonSize = new System.Drawing.Size(20, 20);
151 toolbar.ImageList = toolbar_imagelist;
152 toolbar.Location = new System.Drawing.Point(0, 0);
153 toolbar.ShowToolTips = true;
154 toolbar.Size = new System.Drawing.Size(256, 27);
155 toolbar.TabIndex = 0;
156 toolbar.ButtonClick += new ToolBarButtonClickEventHandler(toolbar_ButtonClick);
158 categorized_toolbarbutton.ImageIndex = 0;
159 categorized_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
160 categorized_toolbarbutton.ToolTipText = Locale.GetText ("Categorized");
162 alphabetic_toolbarbutton.ImageIndex = 1;
163 alphabetic_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
164 alphabetic_toolbarbutton.ToolTipText = Locale.GetText ("Alphabetic");
166 separator_toolbarbutton.Style = ToolBarButtonStyle.Separator;
168 propertypages_toolbarbutton.Enabled = false;
169 propertypages_toolbarbutton.ImageIndex = 2;
170 propertypages_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
171 propertypages_toolbarbutton.ToolTipText = "Property Pages";
174 reset_menuitem = context_menu.MenuItems.Add("Reset");
175 reset_menuitem.Click +=new EventHandler(OnResetPropertyClick);
176 context_menu.MenuItems.Add("-");
177 description_menuitem = context_menu.MenuItems.Add("Description");
178 description_menuitem.Click += new EventHandler(OnDescriptionClick);
179 description_menuitem.Checked = this.HelpVisible;
180 this.ContextMenu = context_menu;
181 toolbar.ContextMenu = context_menu;
183 BorderHelperControl helper = new BorderHelperControl ();
184 helper.Dock = DockStyle.Fill;
185 helper.Controls.Add (property_grid_view);
187 this.Controls.Add(helper);
188 this.Controls.Add(toolbar);
189 this.Controls.Add(splitter);
190 this.Controls.Add(help_panel);
191 this.Name = "PropertyGrid";
192 this.Size = new System.Drawing.Size(256, 400);
194 UpdateToolBarButtons();
196 #endregion // Constructors
198 #region Public Instance Properties
200 [BrowsableAttribute(false)]
201 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
202 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
203 public AttributeCollection BrowsableAttributes {
205 return browsable_attributes;
209 if (browsable_attributes == value) {
213 browsable_attributes = value;
218 [EditorBrowsable(EditorBrowsableState.Never)]
219 public override bool AutoScroll {
221 return base.AutoScroll;
224 base.AutoScroll = value;
228 public override Color BackColor {
230 return base.BackColor;
234 base.BackColor = value;
235 toolbar.BackColor = value;
241 [EditorBrowsable(EditorBrowsableState.Never)]
242 public override Image BackgroundImage {
244 return base.BackgroundImage;
247 base.BackgroundImage = value;
252 [BrowsableAttribute(false)]
253 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
254 public virtual bool CanShowCommands {
256 return can_show_commands;
260 public Color CommandsBackColor {
262 return commands_back_color;
266 if (commands_back_color == value) {
269 commands_back_color = value;
273 public Color CommandsForeColor {
275 return commands_fore_color;
279 if (commands_fore_color == value) {
282 commands_fore_color = value;
286 [BrowsableAttribute(false)]
287 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
288 public virtual bool CommandsVisible {
290 return commands_visible;
294 [DefaultValue(false)]
295 public virtual bool CommandsVisibleIfAvailable {
297 return commands_visible_if_available;
301 if (commands_visible_if_available == value) {
304 commands_visible_if_available = value;
308 [BrowsableAttribute(false)]
309 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
310 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
311 public Point ContextMenuDefaultLocation {
313 return context_menu_default_location;
318 [EditorBrowsable(EditorBrowsableState.Never)]
319 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
320 public new Control.ControlCollection Controls {
322 return base.Controls;
327 [EditorBrowsable(EditorBrowsableState.Never)]
328 public override Color ForeColor {
330 return base.ForeColor;
333 base.ForeColor = value;
337 public Color HelpBackColor {
339 return help_panel.BackColor;
342 if (help_panel.BackColor == value) {
346 help_panel.BackColor = value;
350 public Color HelpForeColor {
352 return help_panel.ForeColor;
356 if (help_panel.ForeColor == value) {
360 help_panel.ForeColor = value;
366 public virtual bool HelpVisible {
368 return help_panel.Visible;
372 if (help_panel.Visible == value) {
376 help_panel.Visible = value;
380 public bool LargeButtons {
382 return large_buttons;
386 if (large_buttons == value) {
390 large_buttons = value;
394 public Color LineColor {
400 if (line_color == value) {
408 [DefaultValue(PropertySort.CategorizedAlphabetical)]
409 public PropertySort PropertySort {
411 return property_sort;
415 if (!Enum.IsDefined (typeof (PropertySort), value)) {
416 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for PropertySort", value));
419 if (property_sort == value) {
423 property_sort = value;
425 UpdateToolBarButtons();
427 property_grid_view.Refresh();
429 if (PropertySortChanged != null) {
430 PropertySortChanged(this, EventArgs.Empty);
435 [BrowsableAttribute(false)]
436 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
437 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
438 public PropertyTabCollection PropertyTabs {
440 return property_tabs;
444 [BrowsableAttribute(false)]
445 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
446 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
447 public GridItem SelectedGridItem {
449 return selected_grid_item;
453 if (selected_grid_item == value) {
457 GridItem oldItem = selected_grid_item;
458 selected_grid_item = value;
459 this.help_title_label.Text = selected_grid_item.Label;
460 if (selected_grid_item.PropertyDescriptor != null)
461 this.help_description_label.Text = selected_grid_item.PropertyDescriptor.Description;
463 current_property_value = value.Value;
464 if (oldItem != null && oldItem.PropertyDescriptor != null) {
465 for (int i = 0; i < ((GridEntry)oldItem).SelectedObjects.Length; i ++) {
466 object target = GetTarget (oldItem, i);
467 oldItem.PropertyDescriptor.RemoveValueChanged(target, new EventHandler(HandlePropertyValueChanged));
470 if (selected_grid_item.PropertyDescriptor != null) {
471 for (int i = 0; i < ((GridEntry)selected_grid_item).SelectedObjects.Length; i ++) {
472 object target = GetTarget (selected_grid_item, i);
473 selected_grid_item.PropertyDescriptor.AddValueChanged(target, new EventHandler(HandlePropertyValueChanged));
476 OnSelectedGridItemChanged(new SelectedGridItemChangedEventArgs (oldItem, selected_grid_item));
480 private void HandlePropertyValueChanged(object sender, EventArgs e) {
481 OnPropertyValueChanged(new PropertyValueChangedEventArgs( selected_grid_item, current_property_value));
485 [TypeConverter("System.Windows.Forms.PropertyGrid+SelectedObjectConverter, " + Consts.AssemblySystem_Windows_Forms)]
486 public object SelectedObject {
488 if (selected_objects.Length > 0)
489 return selected_objects[0];
495 SelectedObjects = new object[0];
497 SelectedObjects = new object[] {value};
502 [BrowsableAttribute(false)]
503 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
504 public object[] SelectedObjects {
506 return selected_objects;
511 for (int i = 0; i < value.Length; i++) {
512 if (value [i] == null)
513 throw new ArgumentException (String.Format ("Item {0} in the objs array is null.", i));
515 selected_objects = value;
517 selected_objects = new object [0];
520 if (selected_objects.Length > 0) {
521 PropertyTabAttribute[] propTabs = (PropertyTabAttribute[])this.SelectedObject.GetType().GetCustomAttributes(typeof(PropertyTabAttribute),true);
522 if (propTabs.Length > 0) {
523 foreach (Type tabType in propTabs[0].TabClasses) {
524 this.PropertyTabs.AddTabType(tabType);
529 RefreshTabs(PropertyTabScope.Component);
531 if (root_grid_item != null) {
532 /* find the first non category grid item and select it */
533 SelectedGridItem = FindFirstItem (root_grid_item);
535 property_grid_view.Refresh();
536 OnSelectedObjectsChanged (EventArgs.Empty);
540 [BrowsableAttribute(false)]
541 [EditorBrowsable(EditorBrowsableState.Advanced)]
542 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
543 public PropertyTab SelectedTab {
549 public override ISite Site {
561 public virtual bool ToolbarVisible {
563 return toolbar.Visible;
567 if (toolbar.Visible == value) {
571 toolbar.Visible = value;
575 public Color ViewBackColor {
577 return property_grid_view.BackColor;
581 if (property_grid_view.BackColor == value) {
585 property_grid_view.BackColor = value;
589 public Color ViewForeColor {
591 return property_grid_view.ForeColor;
595 if (property_grid_view.ForeColor == value) {
599 property_grid_view.ForeColor = value;
603 #endregion // Public Instance Properties
605 #region Protected Instance Properties
607 protected override Size DefaultSize {
609 return base.DefaultSize;
615 [EditorBrowsable(EditorBrowsableState.Advanced)]
616 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
617 protected virtual Type DefaultTabType {
619 return typeof(PropertiesTab);
623 protected bool DrawFlatToolbar {
625 return (toolbar.Appearance == ToolBarAppearance.Flat);
629 toolbar.Appearance = ToolBarAppearance.Flat;
631 toolbar.Appearance = ToolBarAppearance.Normal;
635 protected override bool ShowFocusCues {
637 return base.ShowFocusCues;
641 #endregion // Protected Instance Properties
643 #region Public Instance Methods
645 protected override void Dispose(bool val) {
649 [MonoTODO ("should this be recursive? or just the toplevel items?")]
650 public void CollapseAllGridItems () {
651 if (root_grid_item != null) {
652 foreach (GridItem item in root_grid_item.GridItems) {
653 item.Expanded = false;
658 [MonoTODO ("should this be recursive? or just the toplevel items?")]
659 public void ExpandAllGridItems () {
660 if (root_grid_item != null) {
661 foreach (GridItem item in root_grid_item.GridItems) {
662 item.Expanded = true;
667 public override void Refresh () {
671 public void RefreshTabs (PropertyTabScope tabScope) {
673 /*button = new ToolBarButton("C");
674 button.ImageIndex = 0;
675 this.toolbar.Buttons.Add(button);
676 button = new ToolBarButton();
677 button.ImageIndex = 0;
678 button.Style = ToolBarButtonStyle.Separator;
679 this.toolbar.Buttons.Add(button);
680 foreach (PropertyTab tab in this.PropertyTabs)
683 int index = toolbar.ImageList.Images.Count;
684 this.toolbar.ImageList.Images.Add(tab.Bitmap);
685 button = new ToolBarButton();
686 button.ImageIndex = index;
687 this.toolbar.Buttons.Add(button);
692 public void ResetSelectedProperty() {
693 if (selected_grid_item == null || selected_grid_item.PropertyDescriptor == null)
696 selected_grid_item.PropertyDescriptor.ResetValue(SelectedObject);
698 #endregion // Public Instance Methods
700 #region Protected Instance Methods
702 protected virtual PropertyTab CreatePropertyTab(Type tabType) {
703 return (PropertyTab)Activator.CreateInstance(tabType);
707 protected void OnComComponentNameChanged(ComponentRenameEventArgs e) {
708 throw new NotImplementedException();
711 protected override void OnFontChanged(EventArgs e) {
712 base.OnFontChanged (e);
715 protected override void OnGotFocus(EventArgs e) {
719 protected override void OnHandleCreated (EventArgs e) {
720 base.OnHandleCreated (e);
723 protected override void OnHandleDestroyed (EventArgs e) {
724 base.OnHandleDestroyed (e);
727 protected override void OnMouseDown (MouseEventArgs e) {
728 base.OnMouseDown (e);
731 protected override void OnMouseMove (MouseEventArgs e) {
732 base.OnMouseMove (e);
735 protected override void OnMouseUp (MouseEventArgs e) {
740 protected void OnNotifyPropertyValueUIItemsChanged(object sender, EventArgs e) {
743 protected override void OnPaint (PaintEventArgs pevent) {
744 pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
745 base.OnPaint (pevent);
749 protected virtual void OnPropertyTabChanged (PropertyTabChangedEventArgs e) {
750 throw new NotImplementedException();
753 protected virtual void OnPropertyValueChanged (PropertyValueChangedEventArgs e) {
754 if (PropertyValueChanged != null) {
755 PropertyValueChanged(this, e);
756 current_property_value = selected_grid_item.Value;
760 protected override void OnResize (EventArgs e) {
764 protected virtual void OnSelectedGridItemChanged (SelectedGridItemChangedEventArgs e) {
765 if (SelectedGridItemChanged != null) {
766 SelectedGridItemChanged(this, e);
770 protected virtual void OnSelectedObjectsChanged (EventArgs e) {
771 if (SelectedObjectsChanged != null) {
772 SelectedObjectsChanged(this, e);
776 protected override void OnSystemColorsChanged (EventArgs e) {
777 base.OnSystemColorsChanged (e);
780 protected override void OnVisibleChanged (EventArgs e) {
781 base.OnVisibleChanged (e);
784 protected override bool ProcessDialogKey (Keys keyData) {
785 return base.ProcessDialogKey (keyData);
788 protected override void ScaleCore (float dx, float dy) {
789 base.ScaleCore (dx, dy);
793 protected void ShowEventsButton(bool value) {
794 throw new NotImplementedException();
797 protected override void WndProc (ref Message m) {
798 base.WndProc (ref m);
803 public event EventHandler PropertySortChanged;
804 public event PropertyTabChangedEventHandler PropertyTabChanged;
805 public event PropertyValueChangedEventHandler PropertyValueChanged;
806 public event SelectedGridItemChangedEventHandler SelectedGridItemChanged;
807 public event EventHandler SelectedObjectsChanged;
810 [EditorBrowsable(EditorBrowsableState.Never)]
811 public new event EventHandler BackgroundImageChanged {
812 add { base.BackgroundImageChanged += value; }
813 remove { base.BackgroundImageChanged -= value; }
817 [EditorBrowsable(EditorBrowsableState.Never)]
818 public new event EventHandler ForeColorChanged {
819 add { base.ForeColorChanged += value; }
820 remove { base.ForeColorChanged -= value; }
824 #region Com2Interop.IComPropertyBrowser Interface
826 bool ComponentModel.Com2Interop.IComPropertyBrowser.InPropertySet {
828 throw new NotImplementedException();
833 void ComponentModel.Com2Interop.IComPropertyBrowser.DropDownDone() {
834 throw new NotImplementedException();
838 bool ComponentModel.Com2Interop.IComPropertyBrowser.EnsurePendingChangesCommitted() {
839 throw new NotImplementedException();
843 void ComponentModel.Com2Interop.IComPropertyBrowser.HandleF4() {
844 throw new NotImplementedException();
848 void ComponentModel.Com2Interop.IComPropertyBrowser.LoadState(Microsoft.Win32.RegistryKey key) {
849 throw new NotImplementedException();
853 void ComponentModel.Com2Interop.IComPropertyBrowser.SaveState(Microsoft.Win32.RegistryKey key) {
854 throw new NotImplementedException();
858 private event ComponentRenameEventHandler com_component_name_changed;
859 event ComponentRenameEventHandler ComponentModel.Com2Interop.IComPropertyBrowser.ComComponentNameChanged {
860 add { com_component_name_changed += value; }
861 remove { com_component_name_changed -= value; }
863 #endregion // Com2Interop.IComPropertyBrowser Interface
865 #region PropertyTabCollection Class
866 public class PropertyTabCollection : ICollection, IEnumerable {
867 System.Collections.ArrayList list;
868 #region Private Constructors
869 internal PropertyTabCollection() {
870 list = new ArrayList();
873 #endregion // Private Constructors
875 public PropertyTab this[int index] {
877 return (PropertyTab)list[index];
881 #region ICollection Members
882 bool ICollection.IsSynchronized {
884 return list.IsSynchronized;
888 void ICollection.CopyTo(Array array, int index) {
889 list.CopyTo(array, index);
892 object ICollection.SyncRoot {
894 return list.SyncRoot;
900 #region IEnumerable Members
901 public IEnumerator GetEnumerator() {
902 return list.GetEnumerator();
907 #region ICollection Members
916 #region Public Instance Methods
917 public void AddTabType(System.Type propertyTabType) {
918 list.Add(Activator.CreateInstance(propertyTabType));
921 public void AddTabType(System.Type propertyTabType,
922 System.ComponentModel.PropertyTabScope tabScope) {
923 AddTabType(propertyTabType);
926 public void Clear(System.ComponentModel.PropertyTabScope tabScope) {
927 throw new NotImplementedException();
930 public void RemoveTabType(System.Type propertyTabType) {
931 throw new NotImplementedException();
935 #endregion // PropertyTabCollection Class
937 #region Private Helper Methods
939 public GridItem FindFirstItem (GridItem root)
941 if (root.GridItemType == GridItemType.Property)
944 foreach (GridItem item in root.GridItems) {
945 GridItem subitem = FindFirstItem (item);
954 private void toolbar_ButtonClick (object sender, ToolBarButtonClickEventArgs e) {
955 if (e.Button == alphabetic_toolbarbutton) {
956 this.PropertySort = PropertySort.Alphabetical;
958 else if (e.Button == categorized_toolbarbutton) {
959 this.PropertySort = PropertySort.Categorized;
963 internal void UpdateToolBarButtons () {
964 if (PropertySort == PropertySort.Alphabetical) {
965 categorized_toolbarbutton.Pushed = false;
966 alphabetic_toolbarbutton.Pushed = true;
968 else if (PropertySort == PropertySort.Categorized) {
969 categorized_toolbarbutton.Pushed = true;
970 alphabetic_toolbarbutton.Pushed = false;
973 categorized_toolbarbutton.Pushed = false;
974 alphabetic_toolbarbutton.Pushed = false;
978 private void OnResetPropertyClick (object sender, EventArgs e) {
979 ResetSelectedProperty();
982 private void OnDescriptionClick (object sender, EventArgs e) {
983 this.HelpVisible = !this.HelpVisible;
984 description_menuitem.Checked = this.HelpVisible;
988 private void ReflectObjects () {
989 if (selected_objects.Length > 0) {
990 root_grid_item = new RootGridEntry (property_grid_view,
991 selected_objects.Length > 1 ? selected_objects : selected_objects[0]);
993 PopulateMergedGridItems (selected_objects, root_grid_item.GridItems, true, root_grid_item);
997 private void PopulateMergedGridItems (object[] objs, GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item)
999 ArrayList intersection = null;
1001 for (int i = 0; i < objs.Length; i ++) {
1002 if (objs [i] == null)
1005 ArrayList new_intersection = new ArrayList ();
1006 Type type = objs[i].GetType();
1008 /* i tried using filter attributes, but there's no way to do it for EditorBrowsableAttributes,
1009 since that type lacks an override for IsDefaultAttribute, and for some reason the
1010 BrowsableAttribute.Yes filter wasn't working */
1011 PropertyDescriptorCollection properties = null;
1013 if (typeof (ICustomTypeDescriptor).IsAssignableFrom (type)) {
1014 properties = ((ICustomTypeDescriptor)objs[i]).GetProperties ();
1016 if (properties == null) {
1017 TypeConverter cvt = TypeDescriptor.GetConverter (objs[i]);
1018 properties = cvt.GetProperties (objs[i]);
1020 if (properties == null) {
1021 properties = TypeDescriptor.GetProperties (objs[i]);
1024 foreach (PropertyDescriptor p in (i == 0 ? (ICollection)properties : (ICollection)intersection)) {
1025 PropertyDescriptor property = (i == 0 ? p : properties [p.Name]);
1026 if (property == null) {
1027 /* since the property doesn't exist in at least one of the other types,
1030 else if (!property.IsBrowsable
1031 || (objs.Length > 1 && property.Attributes.Contains (MergablePropertyAttribute.No))
1032 || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Never))
1033 || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Advanced))) {
1034 /* if the property isn't supposed to be displayed in the merged view,
1038 Type p_type = p.ComponentType;
1039 Type property_type = property.ComponentType;
1041 if (p_type.IsAssignableFrom (type))
1042 new_intersection.Add (p);
1043 else if (property_type.IsAssignableFrom (p_type))
1044 new_intersection.Add (property);
1048 intersection = new_intersection;
1051 if (intersection != null && intersection.Count > 0)
1052 PopulateGridItemsFromProperties (objs, intersection, grid_item_coll, recurse, parent_grid_item);
1055 private void PopulateGridItemsFromProperties (object[] objs, ArrayList properties,
1056 GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item) {
1057 foreach (PropertyDescriptor property in properties) {
1059 GridEntry grid_entry = new GridEntry (property_grid_view, objs, property);
1060 grid_entry.SetParent (parent_grid_item);
1061 if (property_sort == PropertySort.Alphabetical || /* XXX */property_sort == PropertySort.NoSort || !recurse) {
1062 if (grid_item_coll[property.Name] == null) {
1063 grid_item_coll.Add(property.Name,grid_entry);
1064 grid_entry.SetParent ((GridEntry)parent_grid_item);
1067 else if (property_sort == PropertySort.Categorized || property_sort == PropertySort.CategorizedAlphabetical) {
1069 string category = property.Category;
1070 CategoryGridEntry cat_item = grid_item_coll[category] as CategoryGridEntry;
1071 if (cat_item == null) {
1072 cat_item = new CategoryGridEntry (property_grid_view, category);
1073 cat_item.SetParent (parent_grid_item);
1074 grid_item_coll.Add (category, cat_item);
1076 if (cat_item.GridItems[property.Name] == null) {
1077 cat_item.GridItems.Add(property.Name,grid_entry);
1078 grid_entry.SetParent (cat_item);
1082 if (recurse && property.Converter != null && property.Converter.GetPropertiesSupported()) {
1083 object[] subobjs = new object[objs.Length];
1084 for (int i = 0; i < objs.Length; i ++)
1085 subobjs[i] = property.GetValue (objs[i]);
1086 PopulateMergedGridItems (subobjs, grid_entry.GridItems, false, grid_entry);
1088 grid_entry.Expanded = false;
1092 private void help_panel_Paint(object sender, PaintEventArgs e) {
1093 e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(help_panel.BackColor), help_panel.ClientRectangle );
1094 e.Graphics.DrawRectangle(SystemPens.ControlDark, 0,0,help_panel.Width-1,help_panel.Height-1 );
1097 internal object GetTarget (GridItem item, int selected_index)
1099 object target = ((GridEntry)item).SelectedObjects[selected_index];
1101 while (item.Parent != null && item.Parent.GridItemType != GridItemType.Property)
1104 if (item.Parent != null && item.Parent.PropertyDescriptor != null)
1105 target = item.Parent.PropertyDescriptor.GetValue (((GridEntry)item.Parent).SelectedObjects[selected_index]);
1109 #endregion // Private Helper Methods
1114 public bool UseCompatibleTextRendering {
1116 return use_compatible_text_rendering;
1120 use_compatible_text_rendering = value;
1125 // as we can not change the color for BorderStyle.FixedSingle and we need the correct
1126 // ClientRectangle so that the ScrollBar doesn't draw over the border we need this class
1127 internal class BorderHelperControl : Control {
1129 public BorderHelperControl ()
1131 BackColor = ThemeEngine.Current.ColorWindow;
1134 protected override void OnPaint (PaintEventArgs e)
1136 e.Graphics.DrawRectangle (SystemPens.ControlDark, 0 , 0 , Width - 1, Height - 1);
1140 protected override void OnSizeChanged (EventArgs e)
1142 if (Controls.Count == 1) {
1143 Control control = Controls [0];
1145 if (control.Location.X != 1 || control.Location.Y != 1)
1146 control.Location = new Point (1, 1);
1148 control.Width = ClientRectangle.Width - 2;
1149 control.Height = ClientRectangle.Height - 2;
1151 base.OnSizeChanged (e);
1155 // needed! this little helper makes it possible to draw a different toolbar border
1156 // and toolbar backcolor in ThemeWin32Classic
1157 internal class PropertyToolBar : ToolBar {}
1160 [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")]
1161 internal class SelectedObjectConverter : TypeConverter