* TextBoxBase.cs: Take HideSelection into account when
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / PropertyGrid.cs
blobc6fa7032160a0f730ca454cb85b9a32d15679e8b
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:
8 //
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.
22 // Authors:
23 // Jonathan Chambers (jonathan.chambers@ansys.com)
26 // NOT COMPLETE
28 using System;
29 using System.Drawing;
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 MenuItem reset_menuitem;
77 private MenuItem description_menuitem;
78 private object current_property_value;
80 #endregion // Private Members
82 #region Contructors
83 public PropertyGrid() {
84 selected_objects = new object[0];
85 property_tabs = new PropertyTabCollection();
87 line_color = SystemColors.ScrollBar;
88 line_color = SystemColors.ScrollBar;
89 browsable_attributes = new AttributeCollection(new Attribute[] {});
90 commands_visible_if_available = false;
91 property_sort = PropertySort.Categorized;
93 property_grid_view = new PropertyGridView(this);
95 splitter = new Splitter();
96 splitter.Dock = DockStyle.Bottom;
98 help_panel = new Panel();
99 help_panel.Dock = DockStyle.Bottom;
100 //help_panel.DockPadding.All = 3;
101 help_panel.Height = 50;
102 help_panel.BackColor = SystemColors.Control;
105 help_title_label = new Label();
106 help_title_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
107 help_title_label.Name = "help_title_label";
108 help_title_label.Font = new Font(this.Font,FontStyle.Bold);
109 help_title_label.Location = new Point(2,2);
110 help_title_label.Height = 17;
111 help_title_label.Width = help_panel.Width - 4;
114 help_description_label = new Label();
115 help_description_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
116 help_description_label.Name = "help_description_label";
117 help_description_label.Font = this.Font;
118 help_description_label.Location = new Point(2,help_title_label.Top+help_title_label.Height);
119 help_description_label.Width = help_panel.Width - 4;
120 help_description_label.Height = help_panel.Height - help_description_label.Top - 2;
122 help_panel.Controls.Add(help_description_label);
123 help_panel.Controls.Add(help_title_label);
124 help_panel.Paint+=new PaintEventHandler(help_panel_Paint);
126 toolbar = new PropertyToolBar();
127 toolbar.Dock = DockStyle.Top;
128 categorized_toolbarbutton = new ToolBarButton();
129 alphabetic_toolbarbutton = new ToolBarButton();
130 separator_toolbarbutton = new ToolBarButton();
131 propertypages_toolbarbutton = new ToolBarButton();
132 ContextMenu context_menu = new ContextMenu();
134 toolbar_imagelist = new ImageList();
135 toolbar_imagelist.ColorDepth = ColorDepth.Depth32Bit;
136 toolbar_imagelist.ImageSize = new System.Drawing.Size(16, 16);
137 toolbar_imagelist.TransparentColor = System.Drawing.Color.Transparent;
138 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_category") );
139 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_alphabetical") );
140 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_tab_properties") );
142 toolbar.Appearance = ToolBarAppearance.Flat;
143 toolbar.AutoSize = false;
144 toolbar.Buttons.AddRange(new ToolBarButton[] {categorized_toolbarbutton,
145 alphabetic_toolbarbutton,
146 separator_toolbarbutton,
147 propertypages_toolbarbutton});
149 toolbar.ButtonSize = new System.Drawing.Size(20, 20);
150 toolbar.ImageList = toolbar_imagelist;
151 toolbar.Location = new System.Drawing.Point(0, 0);
152 toolbar.ShowToolTips = true;
153 toolbar.Size = new System.Drawing.Size(256, 27);
154 toolbar.TabIndex = 0;
155 toolbar.ButtonClick += new ToolBarButtonClickEventHandler(toolbar_ButtonClick);
157 categorized_toolbarbutton.ImageIndex = 0;
158 categorized_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
159 categorized_toolbarbutton.ToolTipText = Locale.GetText ("Categorized");
161 alphabetic_toolbarbutton.ImageIndex = 1;
162 alphabetic_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
163 alphabetic_toolbarbutton.ToolTipText = Locale.GetText ("Alphabetic");
165 separator_toolbarbutton.Style = ToolBarButtonStyle.Separator;
167 propertypages_toolbarbutton.Enabled = false;
168 propertypages_toolbarbutton.ImageIndex = 2;
169 propertypages_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
170 propertypages_toolbarbutton.ToolTipText = "Property Pages";
173 reset_menuitem = context_menu.MenuItems.Add("Reset");
174 reset_menuitem.Click +=new EventHandler(OnResetPropertyClick);
175 context_menu.MenuItems.Add("-");
176 description_menuitem = context_menu.MenuItems.Add("Description");
177 description_menuitem.Click += new EventHandler(OnDescriptionClick);
178 description_menuitem.Checked = this.HelpVisible;
179 this.ContextMenu = context_menu;
180 toolbar.ContextMenu = context_menu;
182 BorderHelperControl helper = new BorderHelperControl ();
183 helper.Dock = DockStyle.Fill;
184 helper.Controls.Add (property_grid_view);
186 this.Controls.Add(helper);
187 this.Controls.Add(toolbar);
188 this.Controls.Add(splitter);
189 this.Controls.Add(help_panel);
190 this.Name = "PropertyGrid";
191 this.Size = new System.Drawing.Size(256, 400);
193 UpdateToolBarButtons();
195 #endregion // Constructors
197 #region Public Instance Properties
199 [BrowsableAttribute(false)]
200 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
201 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
202 public AttributeCollection BrowsableAttributes {
203 get {
204 return browsable_attributes;
207 set {
208 if (browsable_attributes == value) {
209 return;
212 browsable_attributes = value;
216 [Browsable(false)]
217 [EditorBrowsable(EditorBrowsableState.Never)]
218 public override bool AutoScroll {
219 get {
220 return base.AutoScroll;
222 set {
223 base.AutoScroll = value;
227 public override Color BackColor {
228 get {
229 return base.BackColor;
232 set {
233 base.BackColor = value;
234 toolbar.BackColor = value;
235 Refresh ();
239 [Browsable(false)]
240 [EditorBrowsable(EditorBrowsableState.Never)]
241 public override Image BackgroundImage {
242 get {
243 return base.BackgroundImage;
245 set {
246 base.BackgroundImage = value;
251 [BrowsableAttribute(false)]
252 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
253 public virtual bool CanShowCommands {
254 get {
255 return can_show_commands;
259 public Color CommandsBackColor {
260 get {
261 return commands_back_color;
264 set {
265 if (commands_back_color == value) {
266 return;
268 commands_back_color = value;
272 public Color CommandsForeColor {
273 get {
274 return commands_fore_color;
277 set {
278 if (commands_fore_color == value) {
279 return;
281 commands_fore_color = value;
285 [BrowsableAttribute(false)]
286 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
287 public virtual bool CommandsVisible {
288 get {
289 return commands_visible;
293 [DefaultValue(false)]
294 public virtual bool CommandsVisibleIfAvailable {
295 get {
296 return commands_visible_if_available;
299 set {
300 if (commands_visible_if_available == value) {
301 return;
303 commands_visible_if_available = value;
307 [BrowsableAttribute(false)]
308 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
309 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
310 public Point ContextMenuDefaultLocation {
311 get {
312 return context_menu_default_location;
316 [Browsable(false)]
317 [EditorBrowsable(EditorBrowsableState.Never)]
318 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
319 public new Control.ControlCollection Controls {
320 get {
321 return base.Controls;
325 [Browsable(false)]
326 [EditorBrowsable(EditorBrowsableState.Never)]
327 public override Color ForeColor {
328 get {
329 return base.ForeColor;
331 set {
332 base.ForeColor = value;
336 public Color HelpBackColor {
337 get {
338 return help_panel.BackColor;
340 set {
341 if (help_panel.BackColor == value) {
342 return;
345 help_panel.BackColor = value;
349 public Color HelpForeColor {
350 get {
351 return help_panel.ForeColor;
354 set {
355 if (help_panel.ForeColor == value) {
356 return;
359 help_panel.ForeColor = value;
363 [DefaultValue(true)]
364 [Localizable(true)]
365 public virtual bool HelpVisible {
366 get {
367 return help_panel.Visible;
370 set {
371 if (help_panel.Visible == value) {
372 return;
375 help_panel.Visible = value;
379 public bool LargeButtons {
380 get {
381 return large_buttons;
384 set {
385 if (large_buttons == value) {
386 return;
389 large_buttons = value;
393 public Color LineColor {
394 get {
395 return line_color;
398 set {
399 if (line_color == value) {
400 return;
403 line_color = value;
407 [DefaultValue(PropertySort.CategorizedAlphabetical)]
408 public PropertySort PropertySort {
409 get {
410 return property_sort;
413 set {
414 if (!Enum.IsDefined (typeof (PropertySort), value)) {
415 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for PropertySort", value));
418 if (property_sort == value) {
419 return;
422 property_sort = value;
424 UpdateToolBarButtons();
425 ReflectObjects();
426 property_grid_view.Refresh();
428 EventHandler eh = (EventHandler)(Events [PropertySortChangedEvent]);
429 if (eh != null)
430 eh (this, EventArgs.Empty);
434 [BrowsableAttribute(false)]
435 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
436 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
437 public PropertyTabCollection PropertyTabs {
438 get {
439 return property_tabs;
443 [BrowsableAttribute(false)]
444 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
445 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
446 public GridItem SelectedGridItem {
447 get {
448 return selected_grid_item;
451 set {
452 if (selected_grid_item == value) {
453 return;
456 GridItem oldItem = selected_grid_item;
457 selected_grid_item = value;
458 this.help_title_label.Text = selected_grid_item.Label;
459 if (selected_grid_item.PropertyDescriptor != null)
460 this.help_description_label.Text = selected_grid_item.PropertyDescriptor.Description;
462 current_property_value = value.Value;
463 if (oldItem != null && oldItem.PropertyDescriptor != null) {
464 for (int i = 0; i < ((GridEntry)oldItem).SelectedObjects.Length; i ++) {
465 object target = GetTarget (oldItem, i);
466 oldItem.PropertyDescriptor.RemoveValueChanged(target, new EventHandler(HandlePropertyValueChanged));
469 if (selected_grid_item.PropertyDescriptor != null) {
470 for (int i = 0; i < ((GridEntry)selected_grid_item).SelectedObjects.Length; i ++) {
471 object target = GetTarget (selected_grid_item, i);
472 selected_grid_item.PropertyDescriptor.AddValueChanged(target, new EventHandler(HandlePropertyValueChanged));
475 OnSelectedGridItemChanged(new SelectedGridItemChangedEventArgs (oldItem, selected_grid_item));
479 private void HandlePropertyValueChanged(object sender, EventArgs e) {
480 OnPropertyValueChanged(new PropertyValueChangedEventArgs( selected_grid_item, current_property_value));
483 [DefaultValue(null)]
484 [TypeConverter("System.Windows.Forms.PropertyGrid+SelectedObjectConverter, " + Consts.AssemblySystem_Windows_Forms)]
485 public object SelectedObject {
486 get {
487 if (selected_objects.Length > 0)
488 return selected_objects[0];
489 return null;
492 set {
493 if (value == null)
494 SelectedObjects = new object[0];
495 else
496 SelectedObjects = new object[] {value};
501 [BrowsableAttribute(false)]
502 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
503 public object[] SelectedObjects {
504 get {
505 return selected_objects;
508 set {
509 if (value != null) {
510 for (int i = 0; i < value.Length; i++) {
511 if (value [i] == null)
512 throw new ArgumentException (String.Format ("Item {0} in the objs array is null.", i));
514 selected_objects = value;
515 } else {
516 selected_objects = new object [0];
519 if (selected_objects.Length > 0) {
520 PropertyTabAttribute[] propTabs = (PropertyTabAttribute[])this.SelectedObject.GetType().GetCustomAttributes(typeof(PropertyTabAttribute),true);
521 if (propTabs.Length > 0) {
522 foreach (Type tabType in propTabs[0].TabClasses) {
523 this.PropertyTabs.AddTabType(tabType);
528 RefreshTabs(PropertyTabScope.Component);
529 ReflectObjects();
530 if (root_grid_item != null) {
531 /* find the first non category grid item and select it */
532 SelectedGridItem = FindFirstItem (root_grid_item);
534 property_grid_view.Refresh();
535 OnSelectedObjectsChanged (EventArgs.Empty);
539 [BrowsableAttribute(false)]
540 [EditorBrowsable(EditorBrowsableState.Advanced)]
541 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
542 public PropertyTab SelectedTab {
543 get {
544 return selected_tab;
548 public override ISite Site {
549 get {
550 return base.Site;
553 set {
554 base.Site = value;
559 [DefaultValue(true)]
560 public virtual bool ToolbarVisible {
561 get {
562 return toolbar.Visible;
565 set {
566 if (toolbar.Visible == value) {
567 return;
570 toolbar.Visible = value;
574 public Color ViewBackColor {
575 get {
576 return property_grid_view.BackColor;
579 set {
580 if (property_grid_view.BackColor == value) {
581 return;
584 property_grid_view.BackColor = value;
588 public Color ViewForeColor {
589 get {
590 return property_grid_view.ForeColor;
593 set {
594 if (property_grid_view.ForeColor == value) {
595 return;
598 property_grid_view.ForeColor = value;
602 #endregion // Public Instance Properties
604 #region Protected Instance Properties
606 protected override Size DefaultSize {
607 get {
608 return base.DefaultSize;
613 [Browsable(false)]
614 [EditorBrowsable(EditorBrowsableState.Advanced)]
615 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
616 protected virtual Type DefaultTabType {
617 get {
618 return typeof(PropertiesTab);
622 protected bool DrawFlatToolbar {
623 get {
624 return (toolbar.Appearance == ToolBarAppearance.Flat);
626 set {
627 if (value)
628 toolbar.Appearance = ToolBarAppearance.Flat;
629 else
630 toolbar.Appearance = ToolBarAppearance.Normal;
634 protected override bool ShowFocusCues {
635 get {
636 return base.ShowFocusCues;
640 #endregion // Protected Instance Properties
642 #region Public Instance Methods
644 protected override void Dispose(bool val) {
645 base.Dispose(val);
648 [MonoTODO ("should this be recursive? or just the toplevel items?")]
649 public void CollapseAllGridItems () {
650 if (root_grid_item != null) {
651 foreach (GridItem item in root_grid_item.GridItems) {
652 item.Expanded = false;
657 [MonoTODO ("should this be recursive? or just the toplevel items?")]
658 public void ExpandAllGridItems () {
659 if (root_grid_item != null) {
660 foreach (GridItem item in root_grid_item.GridItems) {
661 item.Expanded = true;
666 public override void Refresh () {
667 base.Refresh ();
670 public void RefreshTabs (PropertyTabScope tabScope) {
672 /*button = new ToolBarButton("C");
673 button.ImageIndex = 0;
674 this.toolbar.Buttons.Add(button);
675 button = new ToolBarButton();
676 button.ImageIndex = 0;
677 button.Style = ToolBarButtonStyle.Separator;
678 this.toolbar.Buttons.Add(button);
679 foreach (PropertyTab tab in this.PropertyTabs)
682 int index = toolbar.ImageList.Images.Count;
683 this.toolbar.ImageList.Images.Add(tab.Bitmap);
684 button = new ToolBarButton();
685 button.ImageIndex = index;
686 this.toolbar.Buttons.Add(button);
691 public void ResetSelectedProperty() {
692 if (selected_grid_item == null || selected_grid_item.PropertyDescriptor == null)
693 return;
695 selected_grid_item.PropertyDescriptor.ResetValue(SelectedObject);
697 #endregion // Public Instance Methods
699 #region Protected Instance Methods
701 protected virtual PropertyTab CreatePropertyTab(Type tabType) {
702 return (PropertyTab)Activator.CreateInstance(tabType);
705 [MonoTODO]
706 protected void OnComComponentNameChanged(ComponentRenameEventArgs e)
708 ComponentRenameEventHandler eh = (ComponentRenameEventHandler)(Events [ComComponentNameChangedEvent]);
709 if (eh != null)
710 eh (this, e);
713 protected override void OnFontChanged(EventArgs e) {
714 base.OnFontChanged (e);
717 protected override void OnGotFocus(EventArgs e) {
718 base.OnGotFocus(e);
721 protected override void OnHandleCreated (EventArgs e) {
722 base.OnHandleCreated (e);
725 protected override void OnHandleDestroyed (EventArgs e) {
726 base.OnHandleDestroyed (e);
729 protected override void OnMouseDown (MouseEventArgs e) {
730 base.OnMouseDown (e);
733 protected override void OnMouseMove (MouseEventArgs e) {
734 base.OnMouseMove (e);
737 protected override void OnMouseUp (MouseEventArgs e) {
738 base.OnMouseUp (e);
741 [MonoTODO]
742 protected void OnNotifyPropertyValueUIItemsChanged(object sender, EventArgs e) {
745 protected override void OnPaint (PaintEventArgs pevent) {
746 pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
747 base.OnPaint (pevent);
750 [MonoTODO]
751 protected virtual void OnPropertyTabChanged (PropertyTabChangedEventArgs e) {
752 throw new NotImplementedException();
755 protected virtual void OnPropertyValueChanged (PropertyValueChangedEventArgs e) {
756 PropertyValueChangedEventHandler eh = (PropertyValueChangedEventHandler)(Events [PropertyValueChangedEvent]);
757 if (eh != null) {
758 eh (this, e);
759 current_property_value = selected_grid_item.Value;
763 protected override void OnResize (EventArgs e) {
764 base.OnResize (e);
767 protected virtual void OnSelectedGridItemChanged (SelectedGridItemChangedEventArgs e) {
768 SelectedGridItemChangedEventHandler eh = (SelectedGridItemChangedEventHandler)(Events [SelectedGridItemChangedEvent]);
769 if (eh != null)
770 eh (this, e);
773 protected virtual void OnSelectedObjectsChanged (EventArgs e) {
774 EventHandler eh = (EventHandler)(Events [SelectedObjectsChangedEvent]);
775 if (eh != null)
776 eh (this, e);
779 protected override void OnSystemColorsChanged (EventArgs e) {
780 base.OnSystemColorsChanged (e);
783 protected override void OnVisibleChanged (EventArgs e) {
784 base.OnVisibleChanged (e);
787 protected override bool ProcessDialogKey (Keys keyData) {
788 return base.ProcessDialogKey (keyData);
791 protected override void ScaleCore (float dx, float dy) {
792 base.ScaleCore (dx, dy);
795 [MonoTODO]
796 protected void ShowEventsButton(bool value) {
797 throw new NotImplementedException();
800 protected override void WndProc (ref Message m) {
801 base.WndProc (ref m);
803 #endregion
805 #region Events
806 static object PropertySortChangedEvent = new object ();
807 static object PropertyTabChangedEvent = new object ();
808 static object PropertyValueChangedEvent = new object ();
809 static object SelectedGridItemChangedEvent = new object ();
810 static object SelectedObjectsChangedEvent = new object ();
812 public event EventHandler PropertySortChanged {
813 add { Events.AddHandler (PropertySortChangedEvent, value); }
814 remove { Events.RemoveHandler (PropertySortChangedEvent, value); }
817 public event PropertyTabChangedEventHandler PropertyTabChanged {
818 add { Events.AddHandler (PropertyTabChangedEvent, value); }
819 remove { Events.RemoveHandler (PropertyTabChangedEvent, value); }
822 public event PropertyValueChangedEventHandler PropertyValueChanged {
823 add { Events.AddHandler (PropertyValueChangedEvent, value); }
824 remove { Events.RemoveHandler (PropertyValueChangedEvent, value); }
827 public event SelectedGridItemChangedEventHandler SelectedGridItemChanged {
828 add { Events.AddHandler (SelectedGridItemChangedEvent, value); }
829 remove { Events.RemoveHandler (SelectedGridItemChangedEvent, value); }
832 public event EventHandler SelectedObjectsChanged {
833 add { Events.AddHandler (SelectedObjectsChangedEvent, value); }
834 remove { Events.RemoveHandler (SelectedObjectsChangedEvent, value); }
837 [Browsable(false)]
838 [EditorBrowsable(EditorBrowsableState.Never)]
839 public new event EventHandler BackgroundImageChanged {
840 add { base.BackgroundImageChanged += value; }
841 remove { base.BackgroundImageChanged -= value; }
844 [Browsable(false)]
845 [EditorBrowsable(EditorBrowsableState.Never)]
846 public new event EventHandler ForeColorChanged {
847 add { base.ForeColorChanged += value; }
848 remove { base.ForeColorChanged -= value; }
850 #endregion
852 #region Com2Interop.IComPropertyBrowser Interface
853 [MonoTODO]
854 bool ComponentModel.Com2Interop.IComPropertyBrowser.InPropertySet {
855 get {
856 throw new NotImplementedException();
860 [MonoTODO]
861 void ComponentModel.Com2Interop.IComPropertyBrowser.DropDownDone() {
862 throw new NotImplementedException();
865 [MonoTODO]
866 bool ComponentModel.Com2Interop.IComPropertyBrowser.EnsurePendingChangesCommitted() {
867 throw new NotImplementedException();
870 [MonoTODO]
871 void ComponentModel.Com2Interop.IComPropertyBrowser.HandleF4() {
872 throw new NotImplementedException();
875 [MonoTODO]
876 void ComponentModel.Com2Interop.IComPropertyBrowser.LoadState(Microsoft.Win32.RegistryKey key) {
877 throw new NotImplementedException();
880 [MonoTODO]
881 void ComponentModel.Com2Interop.IComPropertyBrowser.SaveState(Microsoft.Win32.RegistryKey key) {
882 throw new NotImplementedException();
885 static object ComComponentNameChangedEvent = new object ();
886 event ComponentRenameEventHandler ComponentModel.Com2Interop.IComPropertyBrowser.ComComponentNameChanged {
887 add { Events.AddHandler (ComComponentNameChangedEvent, value); }
888 remove { Events.RemoveHandler (ComComponentNameChangedEvent, value); }
890 #endregion // Com2Interop.IComPropertyBrowser Interface
892 #region PropertyTabCollection Class
893 public class PropertyTabCollection : ICollection, IEnumerable {
894 System.Collections.ArrayList list;
895 #region Private Constructors
896 internal PropertyTabCollection() {
897 list = new ArrayList();
900 #endregion // Private Constructors
902 public PropertyTab this[int index] {
903 get {
904 return (PropertyTab)list[index];
908 #region ICollection Members
909 bool ICollection.IsSynchronized {
910 get {
911 return list.IsSynchronized;
915 void ICollection.CopyTo(Array array, int index) {
916 list.CopyTo(array, index);
919 object ICollection.SyncRoot {
920 get {
921 return list.SyncRoot;
925 #endregion
927 #region IEnumerable Members
928 public IEnumerator GetEnumerator() {
929 return list.GetEnumerator();
932 #endregion
934 #region ICollection Members
935 public int Count {
936 get {
937 return list.Count;
941 #endregion
943 #region Public Instance Methods
944 public void AddTabType(System.Type propertyTabType) {
945 list.Add(Activator.CreateInstance(propertyTabType));
947 [MonoTODO]
948 public void AddTabType(System.Type propertyTabType,
949 System.ComponentModel.PropertyTabScope tabScope) {
950 AddTabType(propertyTabType);
952 [MonoTODO]
953 public void Clear(System.ComponentModel.PropertyTabScope tabScope) {
954 throw new NotImplementedException();
956 [MonoTODO]
957 public void RemoveTabType(System.Type propertyTabType) {
958 throw new NotImplementedException();
960 #endregion
962 #endregion // PropertyTabCollection Class
964 #region Private Helper Methods
966 private GridItem FindFirstItem (GridItem root)
968 if (root.GridItemType == GridItemType.Property)
969 return root;
971 foreach (GridItem item in root.GridItems) {
972 GridItem subitem = FindFirstItem (item);
973 if (subitem != null)
974 return subitem;
977 return null;
981 private void toolbar_ButtonClick (object sender, ToolBarButtonClickEventArgs e) {
982 if (e.Button == alphabetic_toolbarbutton) {
983 this.PropertySort = PropertySort.Alphabetical;
985 else if (e.Button == categorized_toolbarbutton) {
986 this.PropertySort = PropertySort.Categorized;
990 internal void UpdateToolBarButtons () {
991 if (PropertySort == PropertySort.Alphabetical) {
992 categorized_toolbarbutton.Pushed = false;
993 alphabetic_toolbarbutton.Pushed = true;
995 else if (PropertySort == PropertySort.Categorized) {
996 categorized_toolbarbutton.Pushed = true;
997 alphabetic_toolbarbutton.Pushed = false;
999 else {
1000 categorized_toolbarbutton.Pushed = false;
1001 alphabetic_toolbarbutton.Pushed = false;
1005 private void OnResetPropertyClick (object sender, EventArgs e) {
1006 ResetSelectedProperty();
1009 private void OnDescriptionClick (object sender, EventArgs e) {
1010 this.HelpVisible = !this.HelpVisible;
1011 description_menuitem.Checked = this.HelpVisible;
1015 private void ReflectObjects () {
1016 if (selected_objects.Length > 0) {
1017 root_grid_item = new RootGridEntry (property_grid_view,
1018 selected_objects.Length > 1 ? selected_objects : selected_objects[0]);
1020 PopulateMergedGridItems (selected_objects, root_grid_item.GridItems, true, root_grid_item);
1024 private void PopulateMergedGridItems (object[] objs, GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item)
1026 ArrayList intersection = null;
1028 for (int i = 0; i < objs.Length; i ++) {
1029 if (objs [i] == null)
1030 continue;
1032 ArrayList new_intersection = new ArrayList ();
1033 Type type = objs[i].GetType();
1035 /* i tried using filter attributes, but there's no way to do it for EditorBrowsableAttributes,
1036 since that type lacks an override for IsDefaultAttribute, and for some reason the
1037 BrowsableAttribute.Yes filter wasn't working */
1038 PropertyDescriptorCollection properties = null;
1040 if (typeof (ICustomTypeDescriptor).IsAssignableFrom (type)) {
1041 properties = ((ICustomTypeDescriptor)objs[i]).GetProperties ();
1043 if (properties == null) {
1044 TypeConverter cvt = TypeDescriptor.GetConverter (objs[i]);
1045 properties = cvt.GetProperties (objs[i]);
1047 if (properties == null) {
1048 properties = TypeDescriptor.GetProperties (objs[i]);
1051 foreach (PropertyDescriptor p in (i == 0 ? (ICollection)properties : (ICollection)intersection)) {
1052 PropertyDescriptor property = (i == 0 ? p : properties [p.Name]);
1053 if (property == null) {
1054 /* since the property doesn't exist in at least one of the other types,
1055 exclude it */
1057 else if (!property.IsBrowsable
1058 || (objs.Length > 1 && property.Attributes.Contains (MergablePropertyAttribute.No))
1059 || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Never))
1060 || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Advanced))) {
1061 /* if the property isn't supposed to be displayed in the merged view,
1062 excluded it */
1064 else {
1065 Type p_type = p.ComponentType;
1066 Type property_type = property.ComponentType;
1068 if (p_type.IsAssignableFrom (type))
1069 new_intersection.Add (p);
1070 else if (property_type.IsAssignableFrom (p_type))
1071 new_intersection.Add (property);
1075 intersection = new_intersection;
1078 if (intersection != null && intersection.Count > 0)
1079 PopulateGridItemsFromProperties (objs, intersection, grid_item_coll, recurse, parent_grid_item);
1082 private void PopulateGridItemsFromProperties (object[] objs, ArrayList properties,
1083 GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item) {
1084 foreach (PropertyDescriptor property in properties) {
1086 GridEntry grid_entry = new GridEntry (property_grid_view, objs, property);
1087 grid_entry.SetParent (parent_grid_item);
1088 if (property_sort == PropertySort.Alphabetical || /* XXX */property_sort == PropertySort.NoSort || !recurse) {
1089 if (grid_item_coll[property.Name] == null) {
1090 grid_item_coll.Add(property.Name,grid_entry);
1091 grid_entry.SetParent ((GridEntry)parent_grid_item);
1094 else if (property_sort == PropertySort.Categorized || property_sort == PropertySort.CategorizedAlphabetical) {
1096 string category = property.Category;
1097 CategoryGridEntry cat_item = grid_item_coll[category] as CategoryGridEntry;
1098 if (cat_item == null) {
1099 cat_item = new CategoryGridEntry (property_grid_view, category);
1100 cat_item.SetParent (parent_grid_item);
1101 grid_item_coll.Add (category, cat_item);
1103 if (cat_item.GridItems[property.Name] == null) {
1104 cat_item.GridItems.Add(property.Name,grid_entry);
1105 grid_entry.SetParent (cat_item);
1109 if (recurse && property.Converter != null && property.Converter.GetPropertiesSupported()) {
1110 object[] subobjs = new object[objs.Length];
1111 for (int i = 0; i < objs.Length; i ++)
1112 subobjs[i] = property.GetValue (objs[i]);
1113 PopulateMergedGridItems (subobjs, grid_entry.GridItems, false, grid_entry);
1115 grid_entry.Expanded = false;
1119 private void help_panel_Paint(object sender, PaintEventArgs e) {
1120 e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(help_panel.BackColor), help_panel.ClientRectangle );
1121 e.Graphics.DrawRectangle(SystemPens.ControlDark, 0,0,help_panel.Width-1,help_panel.Height-1 );
1124 internal object GetTarget (GridItem item, int selected_index)
1126 object target = ((GridEntry)item).SelectedObjects[selected_index];
1128 while (item.Parent != null && item.Parent.GridItemType != GridItemType.Property)
1129 item = item.Parent;
1131 if (item.Parent != null && item.Parent.PropertyDescriptor != null)
1132 target = item.Parent.PropertyDescriptor.GetValue (((GridEntry)item.Parent).SelectedObjects[selected_index]);
1134 return target;
1136 #endregion // Private Helper Methods
1139 #if NET_2_0
1141 public bool UseCompatibleTextRendering {
1142 get {
1143 return use_compatible_text_rendering;
1146 set {
1147 use_compatible_text_rendering = value;
1150 #endif
1152 // as we can not change the color for BorderStyle.FixedSingle and we need the correct
1153 // ClientRectangle so that the ScrollBar doesn't draw over the border we need this class
1154 internal class BorderHelperControl : Control {
1156 public BorderHelperControl ()
1158 BackColor = ThemeEngine.Current.ColorWindow;
1161 protected override void OnPaint (PaintEventArgs e)
1163 e.Graphics.DrawRectangle (SystemPens.ControlDark, 0 , 0 , Width - 1, Height - 1);
1164 base.OnPaint (e);
1167 protected override void OnSizeChanged (EventArgs e)
1169 if (Controls.Count == 1) {
1170 Control control = Controls [0];
1172 if (control.Location.X != 1 || control.Location.Y != 1)
1173 control.Location = new Point (1, 1);
1175 control.Width = ClientRectangle.Width - 2;
1176 control.Height = ClientRectangle.Height - 2;
1178 base.OnSizeChanged (e);
1182 // needed! this little helper makes it possible to draw a different toolbar border
1183 // and toolbar backcolor in ThemeWin32Classic
1184 internal class PropertyToolBar : ToolBar {}
1187 [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")]
1188 internal class SelectedObjectConverter : TypeConverter