* TextBoxBase.cs: Use the new SuspendRecalc/ResumeRecalc methods
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / PropertyGrid.cs
blob5646d06d53211f45fddbab352f632bce1a76938c
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.Runtime.InteropServices;
36 using System.Windows.Forms.Design;
37 using System.Windows.Forms.PropertyGridInternal;
39 namespace System.Windows.Forms {
40 [Designer("System.Windows.Forms.Design.PropertyGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
41 #if NET_2_0
42 [ClassInterface (ClassInterfaceType.AutoDispatch)]
43 [ComVisible (true)]
44 #endif
45 public class PropertyGrid : System.Windows.Forms.ContainerControl, ComponentModel.Com2Interop.IComPropertyBrowser {
46 #region Private Members
49 private const int GRID_ITEM_HEIGHT = 16;
50 private const int GRID_LEFT_COLUMN_WIDTH = 16;
51 private const int DIVIDER_PADDING = 2;
53 private AttributeCollection browsable_attributes = null;
54 private bool can_show_commands = false;
55 private Color commands_back_color;
56 private Color commands_fore_color;
57 private bool commands_visible;
58 private bool commands_visible_if_available;
59 private Point context_menu_default_location;
60 private bool large_buttons;
61 private Color line_color;
62 private PropertySort property_sort;
63 private PropertyTabCollection property_tabs;
64 private GridItem selected_grid_item;
65 internal GridItem root_grid_item;
66 private object[] selected_objects;
67 private PropertyTab selected_tab;
69 private ImageList toolbar_imagelist;
70 private ToolBarButton categorized_toolbarbutton;
71 private ToolBarButton alphabetic_toolbarbutton;
72 private ToolBarButton separator_toolbarbutton;
73 private ToolBarButton propertypages_toolbarbutton;
75 internal ToolBar toolbar;
76 internal PropertyGridView property_grid_view;
77 internal Splitter splitter;
78 internal Panel help_panel;
79 internal Label help_title_label;
80 internal Label help_description_label;
81 private MenuItem reset_menuitem;
82 private MenuItem description_menuitem;
83 private object current_property_value;
85 #endregion // Private Members
87 #region Contructors
88 public PropertyGrid() {
89 selected_objects = new object[0];
90 property_tabs = new PropertyTabCollection();
92 line_color = SystemColors.ScrollBar;
93 line_color = SystemColors.ScrollBar;
94 browsable_attributes = new AttributeCollection(new Attribute[] {});
95 commands_visible_if_available = false;
96 property_sort = PropertySort.Categorized;
98 property_grid_view = new PropertyGridView(this);
100 splitter = new Splitter();
101 splitter.Dock = DockStyle.Bottom;
103 help_panel = new Panel();
104 help_panel.Dock = DockStyle.Bottom;
105 //help_panel.DockPadding.All = 3;
106 help_panel.Height = 50;
107 help_panel.BackColor = SystemColors.Control;
110 help_title_label = new Label();
111 help_title_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
112 help_title_label.Name = "help_title_label";
113 help_title_label.Font = new Font(this.Font,FontStyle.Bold);
114 help_title_label.Location = new Point(2,2);
115 help_title_label.Height = 17;
116 help_title_label.Width = help_panel.Width - 4;
119 help_description_label = new Label();
120 help_description_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
121 help_description_label.Name = "help_description_label";
122 help_description_label.Font = this.Font;
123 help_description_label.Location = new Point(2,help_title_label.Top+help_title_label.Height);
124 help_description_label.Width = help_panel.Width - 4;
125 help_description_label.Height = help_panel.Height - help_description_label.Top - 2;
127 help_panel.Controls.Add(help_description_label);
128 help_panel.Controls.Add(help_title_label);
129 help_panel.Paint+=new PaintEventHandler(help_panel_Paint);
131 toolbar = new PropertyToolBar();
132 toolbar.Dock = DockStyle.Top;
133 categorized_toolbarbutton = new ToolBarButton();
134 alphabetic_toolbarbutton = new ToolBarButton();
135 separator_toolbarbutton = new ToolBarButton();
136 propertypages_toolbarbutton = new ToolBarButton();
137 ContextMenu context_menu = new ContextMenu();
139 toolbar_imagelist = new ImageList();
140 toolbar_imagelist.ColorDepth = ColorDepth.Depth32Bit;
141 toolbar_imagelist.ImageSize = new System.Drawing.Size(16, 16);
142 toolbar_imagelist.TransparentColor = System.Drawing.Color.Transparent;
143 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_category") );
144 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_alphabetical") );
145 toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_tab_properties") );
147 toolbar.Appearance = ToolBarAppearance.Flat;
148 toolbar.AutoSize = false;
149 toolbar.Buttons.AddRange(new ToolBarButton[] {categorized_toolbarbutton,
150 alphabetic_toolbarbutton,
151 separator_toolbarbutton,
152 propertypages_toolbarbutton});
154 toolbar.ButtonSize = new System.Drawing.Size(20, 20);
155 toolbar.ImageList = toolbar_imagelist;
156 toolbar.Location = new System.Drawing.Point(0, 0);
157 toolbar.ShowToolTips = true;
158 toolbar.Size = new System.Drawing.Size(256, 27);
159 toolbar.TabIndex = 0;
160 toolbar.ButtonClick += new ToolBarButtonClickEventHandler(toolbar_ButtonClick);
162 categorized_toolbarbutton.ImageIndex = 0;
163 categorized_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
164 categorized_toolbarbutton.ToolTipText = Locale.GetText ("Categorized");
166 alphabetic_toolbarbutton.ImageIndex = 1;
167 alphabetic_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
168 alphabetic_toolbarbutton.ToolTipText = Locale.GetText ("Alphabetic");
170 separator_toolbarbutton.Style = ToolBarButtonStyle.Separator;
172 propertypages_toolbarbutton.Enabled = false;
173 propertypages_toolbarbutton.ImageIndex = 2;
174 propertypages_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
175 propertypages_toolbarbutton.ToolTipText = "Property Pages";
178 reset_menuitem = context_menu.MenuItems.Add("Reset");
179 reset_menuitem.Click +=new EventHandler(OnResetPropertyClick);
180 context_menu.MenuItems.Add("-");
181 description_menuitem = context_menu.MenuItems.Add("Description");
182 description_menuitem.Click += new EventHandler(OnDescriptionClick);
183 description_menuitem.Checked = this.HelpVisible;
184 this.ContextMenu = context_menu;
185 toolbar.ContextMenu = context_menu;
187 BorderHelperControl helper = new BorderHelperControl ();
188 helper.Dock = DockStyle.Fill;
189 helper.Controls.Add (property_grid_view);
191 this.Controls.Add(helper);
192 this.Controls.Add(toolbar);
193 this.Controls.Add(splitter);
194 this.Controls.Add(help_panel);
195 this.Name = "PropertyGrid";
196 this.Size = new System.Drawing.Size(256, 400);
198 UpdateToolBarButtons();
200 #endregion // Constructors
202 #region Public Instance Properties
204 [BrowsableAttribute(false)]
205 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
206 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
207 public AttributeCollection BrowsableAttributes {
208 get {
209 return browsable_attributes;
212 set {
213 if (browsable_attributes == value) {
214 return;
217 browsable_attributes = value;
221 [Browsable(false)]
222 [EditorBrowsable(EditorBrowsableState.Never)]
223 public override bool AutoScroll {
224 get {
225 return base.AutoScroll;
227 set {
228 base.AutoScroll = value;
232 public override Color BackColor {
233 get {
234 return base.BackColor;
237 set {
238 base.BackColor = value;
239 toolbar.BackColor = value;
240 Refresh ();
244 [Browsable(false)]
245 [EditorBrowsable(EditorBrowsableState.Never)]
246 public override Image BackgroundImage {
247 get {
248 return base.BackgroundImage;
250 set {
251 base.BackgroundImage = value;
256 [BrowsableAttribute(false)]
257 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
258 public virtual bool CanShowCommands {
259 get {
260 return can_show_commands;
264 public Color CommandsBackColor {
265 get {
266 return commands_back_color;
269 set {
270 if (commands_back_color == value) {
271 return;
273 commands_back_color = value;
277 public Color CommandsForeColor {
278 get {
279 return commands_fore_color;
282 set {
283 if (commands_fore_color == value) {
284 return;
286 commands_fore_color = value;
290 [BrowsableAttribute (false)]
291 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
292 public virtual bool CommandsVisible {
293 get {
294 return commands_visible;
298 #if NET_2_0
299 [DefaultValue (true)]
300 #else
301 [DefaultValue (false)]
302 #endif
303 public virtual bool CommandsVisibleIfAvailable {
304 get {
305 return commands_visible_if_available;
308 set {
309 if (commands_visible_if_available == value) {
310 return;
312 commands_visible_if_available = value;
316 [BrowsableAttribute(false)]
317 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
318 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
319 public Point ContextMenuDefaultLocation {
320 get {
321 return context_menu_default_location;
325 [Browsable(false)]
326 [EditorBrowsable(EditorBrowsableState.Never)]
327 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
328 public new Control.ControlCollection Controls {
329 get {
330 return base.Controls;
334 [Browsable(false)]
335 [EditorBrowsable(EditorBrowsableState.Never)]
336 public override Color ForeColor {
337 get {
338 return base.ForeColor;
340 set {
341 base.ForeColor = value;
345 #if NET_2_0
346 [DefaultValue ("Color [Control]")]
347 #endif
348 public Color HelpBackColor {
349 get {
350 return help_panel.BackColor;
352 set {
353 if (help_panel.BackColor == value) {
354 return;
357 help_panel.BackColor = value;
361 #if NET_2_0
362 [DefaultValue ("Color [ControlText]")]
363 #endif
364 public Color HelpForeColor {
365 get {
366 return help_panel.ForeColor;
369 set {
370 if (help_panel.ForeColor == value) {
371 return;
374 help_panel.ForeColor = value;
378 [DefaultValue(true)]
379 [Localizable(true)]
380 public virtual bool HelpVisible {
381 get {
382 return help_panel.Visible;
385 set {
386 if (help_panel.Visible == value) {
387 return;
390 help_panel.Visible = value;
394 #if NET_2_0
395 [DefaultValue (false)]
396 #endif
397 public bool LargeButtons {
398 get {
399 return large_buttons;
402 set {
403 if (large_buttons == value) {
404 return;
407 large_buttons = value;
411 #if NET_2_0
412 [DefaultValue ("Color [InactiveBorder]")]
413 #endif
414 public Color LineColor {
415 get {
416 return line_color;
419 set {
420 if (line_color == value) {
421 return;
424 line_color = value;
428 [DefaultValue(PropertySort.CategorizedAlphabetical)]
429 public PropertySort PropertySort {
430 get {
431 return property_sort;
434 set {
435 if (!Enum.IsDefined (typeof (PropertySort), value)) {
436 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for PropertySort", value));
439 if (property_sort == value) {
440 return;
443 property_sort = value;
445 UpdateToolBarButtons();
446 ReflectObjects();
447 property_grid_view.Refresh();
449 EventHandler eh = (EventHandler)(Events [PropertySortChangedEvent]);
450 if (eh != null)
451 eh (this, EventArgs.Empty);
455 [BrowsableAttribute(false)]
456 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
457 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
458 public PropertyTabCollection PropertyTabs {
459 get {
460 return property_tabs;
464 [BrowsableAttribute(false)]
465 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
466 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
467 public GridItem SelectedGridItem {
468 get {
469 return selected_grid_item;
472 set {
473 if (selected_grid_item == value) {
474 return;
477 GridItem oldItem = selected_grid_item;
478 selected_grid_item = value;
479 this.help_title_label.Text = selected_grid_item.Label;
480 if (selected_grid_item.PropertyDescriptor != null)
481 this.help_description_label.Text = selected_grid_item.PropertyDescriptor.Description;
483 current_property_value = value.Value;
484 if (oldItem != null && oldItem.PropertyDescriptor != null) {
485 for (int i = 0; i < ((GridEntry)oldItem).SelectedObjects.Length; i ++) {
486 object target = GetTarget (oldItem, i);
487 oldItem.PropertyDescriptor.RemoveValueChanged(target, new EventHandler(HandlePropertyValueChanged));
490 if (selected_grid_item.PropertyDescriptor != null) {
491 for (int i = 0; i < ((GridEntry)selected_grid_item).SelectedObjects.Length; i ++) {
492 object target = GetTarget (selected_grid_item, i);
493 selected_grid_item.PropertyDescriptor.AddValueChanged(target, new EventHandler(HandlePropertyValueChanged));
496 OnSelectedGridItemChanged(new SelectedGridItemChangedEventArgs (oldItem, selected_grid_item));
500 private void HandlePropertyValueChanged(object sender, EventArgs e) {
501 OnPropertyValueChanged(new PropertyValueChangedEventArgs( selected_grid_item, current_property_value));
504 [DefaultValue(null)]
505 [TypeConverter("System.Windows.Forms.PropertyGrid+SelectedObjectConverter, " + Consts.AssemblySystem_Windows_Forms)]
506 public object SelectedObject {
507 get {
508 if (selected_objects.Length > 0)
509 return selected_objects[0];
510 return null;
513 set {
514 if (value == null)
515 SelectedObjects = new object[0];
516 else
517 SelectedObjects = new object[] {value};
522 [BrowsableAttribute(false)]
523 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
524 public object[] SelectedObjects {
525 get {
526 return selected_objects;
529 set {
530 if (value != null) {
531 for (int i = 0; i < value.Length; i++) {
532 if (value [i] == null)
533 throw new ArgumentException (String.Format ("Item {0} in the objs array is null.", i));
535 selected_objects = value;
536 } else {
537 selected_objects = new object [0];
540 if (selected_objects.Length > 0) {
541 PropertyTabAttribute[] propTabs = (PropertyTabAttribute[])this.SelectedObject.GetType().GetCustomAttributes(typeof(PropertyTabAttribute),true);
542 if (propTabs.Length > 0) {
543 foreach (Type tabType in propTabs[0].TabClasses) {
544 this.PropertyTabs.AddTabType(tabType);
549 RefreshTabs(PropertyTabScope.Component);
550 ReflectObjects();
551 if (root_grid_item != null) {
552 /* find the first non category grid item and select it */
553 SelectedGridItem = FindFirstItem (root_grid_item);
555 property_grid_view.Refresh();
556 OnSelectedObjectsChanged (EventArgs.Empty);
560 [BrowsableAttribute(false)]
561 [EditorBrowsable(EditorBrowsableState.Advanced)]
562 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
563 public PropertyTab SelectedTab {
564 get {
565 return selected_tab;
569 public override ISite Site {
570 get {
571 return base.Site;
574 set {
575 base.Site = value;
580 [DefaultValue(true)]
581 public virtual bool ToolbarVisible {
582 get {
583 return toolbar.Visible;
586 set {
587 if (toolbar.Visible == value) {
588 return;
591 toolbar.Visible = value;
595 #if NET_2_0
596 [DefaultValue ("Color [Window]")]
597 #endif
598 public Color ViewBackColor {
599 get {
600 return property_grid_view.BackColor;
603 set {
604 if (property_grid_view.BackColor == value) {
605 return;
608 property_grid_view.BackColor = value;
612 #if NET_2_0
613 [DefaultValue ("Color [WindowText]")]
614 #endif
615 public Color ViewForeColor {
616 get {
617 return property_grid_view.ForeColor;
620 set {
621 if (property_grid_view.ForeColor == value) {
622 return;
625 property_grid_view.ForeColor = value;
629 #endregion // Public Instance Properties
631 #region Protected Instance Properties
633 protected override Size DefaultSize {
634 get {
635 return base.DefaultSize;
640 [Browsable(false)]
641 [EditorBrowsable(EditorBrowsableState.Advanced)]
642 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
643 protected virtual Type DefaultTabType {
644 get {
645 return typeof(PropertiesTab);
649 protected bool DrawFlatToolbar {
650 get {
651 return (toolbar.Appearance == ToolBarAppearance.Flat);
653 set {
654 if (value)
655 toolbar.Appearance = ToolBarAppearance.Flat;
656 else
657 toolbar.Appearance = ToolBarAppearance.Normal;
661 protected override bool ShowFocusCues {
662 get {
663 return base.ShowFocusCues;
667 #endregion // Protected Instance Properties
669 #region Public Instance Methods
671 protected override void Dispose(bool val) {
672 base.Dispose(val);
675 [MonoTODO ("should this be recursive? or just the toplevel items?")]
676 public void CollapseAllGridItems () {
677 if (root_grid_item != null) {
678 foreach (GridItem item in root_grid_item.GridItems) {
679 item.Expanded = false;
684 [MonoTODO ("should this be recursive? or just the toplevel items?")]
685 public void ExpandAllGridItems () {
686 if (root_grid_item != null) {
687 foreach (GridItem item in root_grid_item.GridItems) {
688 item.Expanded = true;
693 public override void Refresh () {
694 base.Refresh ();
697 public void RefreshTabs (PropertyTabScope tabScope) {
699 /*button = new ToolBarButton("C");
700 button.ImageIndex = 0;
701 this.toolbar.Buttons.Add(button);
702 button = new ToolBarButton();
703 button.ImageIndex = 0;
704 button.Style = ToolBarButtonStyle.Separator;
705 this.toolbar.Buttons.Add(button);
706 foreach (PropertyTab tab in this.PropertyTabs)
709 int index = toolbar.ImageList.Images.Count;
710 this.toolbar.ImageList.Images.Add(tab.Bitmap);
711 button = new ToolBarButton();
712 button.ImageIndex = index;
713 this.toolbar.Buttons.Add(button);
718 public void ResetSelectedProperty() {
719 if (selected_grid_item == null || selected_grid_item.PropertyDescriptor == null)
720 return;
722 selected_grid_item.PropertyDescriptor.ResetValue(SelectedObject);
724 #endregion // Public Instance Methods
726 #region Protected Instance Methods
728 protected virtual PropertyTab CreatePropertyTab(Type tabType) {
729 return (PropertyTab)Activator.CreateInstance(tabType);
732 [MonoTODO]
733 protected void OnComComponentNameChanged(ComponentRenameEventArgs e)
735 ComponentRenameEventHandler eh = (ComponentRenameEventHandler)(Events [ComComponentNameChangedEvent]);
736 if (eh != null)
737 eh (this, e);
740 protected override void OnFontChanged(EventArgs e) {
741 base.OnFontChanged (e);
744 protected override void OnGotFocus(EventArgs e) {
745 base.OnGotFocus(e);
748 protected override void OnHandleCreated (EventArgs e) {
749 base.OnHandleCreated (e);
752 protected override void OnHandleDestroyed (EventArgs e) {
753 base.OnHandleDestroyed (e);
756 protected override void OnMouseDown (MouseEventArgs e) {
757 base.OnMouseDown (e);
760 protected override void OnMouseMove (MouseEventArgs e) {
761 base.OnMouseMove (e);
764 protected override void OnMouseUp (MouseEventArgs e) {
765 base.OnMouseUp (e);
768 [MonoTODO]
769 protected void OnNotifyPropertyValueUIItemsChanged(object sender, EventArgs e) {
772 protected override void OnPaint (PaintEventArgs pevent) {
773 pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
774 base.OnPaint (pevent);
777 [MonoTODO]
778 protected virtual void OnPropertyTabChanged (PropertyTabChangedEventArgs e) {
779 throw new NotImplementedException();
782 protected virtual void OnPropertyValueChanged (PropertyValueChangedEventArgs e) {
783 PropertyValueChangedEventHandler eh = (PropertyValueChangedEventHandler)(Events [PropertyValueChangedEvent]);
784 if (eh != null) {
785 eh (this, e);
786 current_property_value = selected_grid_item.Value;
790 protected override void OnResize (EventArgs e) {
791 base.OnResize (e);
794 protected virtual void OnSelectedGridItemChanged (SelectedGridItemChangedEventArgs e) {
795 SelectedGridItemChangedEventHandler eh = (SelectedGridItemChangedEventHandler)(Events [SelectedGridItemChangedEvent]);
796 if (eh != null)
797 eh (this, e);
800 protected virtual void OnSelectedObjectsChanged (EventArgs e) {
801 EventHandler eh = (EventHandler)(Events [SelectedObjectsChangedEvent]);
802 if (eh != null)
803 eh (this, e);
806 protected override void OnSystemColorsChanged (EventArgs e) {
807 base.OnSystemColorsChanged (e);
810 protected override void OnVisibleChanged (EventArgs e) {
811 base.OnVisibleChanged (e);
814 protected override bool ProcessDialogKey (Keys keyData) {
815 return base.ProcessDialogKey (keyData);
818 [EditorBrowsable (EditorBrowsableState.Never)]
819 protected override void ScaleCore (float dx, float dy) {
820 base.ScaleCore (dx, dy);
823 [MonoTODO]
824 protected void ShowEventsButton(bool value) {
825 throw new NotImplementedException();
828 protected override void WndProc (ref Message m) {
829 base.WndProc (ref m);
831 #endregion
833 #region Events
834 static object PropertySortChangedEvent = new object ();
835 static object PropertyTabChangedEvent = new object ();
836 static object PropertyValueChangedEvent = new object ();
837 static object SelectedGridItemChangedEvent = new object ();
838 static object SelectedObjectsChangedEvent = new object ();
840 public event EventHandler PropertySortChanged {
841 add { Events.AddHandler (PropertySortChangedEvent, value); }
842 remove { Events.RemoveHandler (PropertySortChangedEvent, value); }
845 public event PropertyTabChangedEventHandler PropertyTabChanged {
846 add { Events.AddHandler (PropertyTabChangedEvent, value); }
847 remove { Events.RemoveHandler (PropertyTabChangedEvent, value); }
850 public event PropertyValueChangedEventHandler PropertyValueChanged {
851 add { Events.AddHandler (PropertyValueChangedEvent, value); }
852 remove { Events.RemoveHandler (PropertyValueChangedEvent, value); }
855 public event SelectedGridItemChangedEventHandler SelectedGridItemChanged {
856 add { Events.AddHandler (SelectedGridItemChangedEvent, value); }
857 remove { Events.RemoveHandler (SelectedGridItemChangedEvent, value); }
860 public event EventHandler SelectedObjectsChanged {
861 add { Events.AddHandler (SelectedObjectsChangedEvent, value); }
862 remove { Events.RemoveHandler (SelectedObjectsChangedEvent, value); }
865 [Browsable(false)]
866 [EditorBrowsable(EditorBrowsableState.Never)]
867 public new event EventHandler BackgroundImageChanged {
868 add { base.BackgroundImageChanged += value; }
869 remove { base.BackgroundImageChanged -= value; }
872 [Browsable(false)]
873 [EditorBrowsable(EditorBrowsableState.Never)]
874 public new event EventHandler ForeColorChanged {
875 add { base.ForeColorChanged += value; }
876 remove { base.ForeColorChanged -= value; }
878 #endregion
880 #region Com2Interop.IComPropertyBrowser Interface
881 [MonoTODO]
882 bool ComponentModel.Com2Interop.IComPropertyBrowser.InPropertySet {
883 get {
884 throw new NotImplementedException();
888 [MonoTODO]
889 void ComponentModel.Com2Interop.IComPropertyBrowser.DropDownDone() {
890 throw new NotImplementedException();
893 [MonoTODO]
894 bool ComponentModel.Com2Interop.IComPropertyBrowser.EnsurePendingChangesCommitted() {
895 throw new NotImplementedException();
898 [MonoTODO]
899 void ComponentModel.Com2Interop.IComPropertyBrowser.HandleF4() {
900 throw new NotImplementedException();
903 [MonoTODO]
904 void ComponentModel.Com2Interop.IComPropertyBrowser.LoadState(Microsoft.Win32.RegistryKey key) {
905 throw new NotImplementedException();
908 [MonoTODO]
909 void ComponentModel.Com2Interop.IComPropertyBrowser.SaveState(Microsoft.Win32.RegistryKey key) {
910 throw new NotImplementedException();
913 static object ComComponentNameChangedEvent = new object ();
914 event ComponentRenameEventHandler ComponentModel.Com2Interop.IComPropertyBrowser.ComComponentNameChanged {
915 add { Events.AddHandler (ComComponentNameChangedEvent, value); }
916 remove { Events.RemoveHandler (ComComponentNameChangedEvent, value); }
918 #endregion // Com2Interop.IComPropertyBrowser Interface
920 #region PropertyTabCollection Class
921 public class PropertyTabCollection : ICollection, IEnumerable {
922 System.Collections.ArrayList list;
923 #region Private Constructors
924 internal PropertyTabCollection() {
925 list = new ArrayList();
928 #endregion // Private Constructors
930 public PropertyTab this[int index] {
931 get {
932 return (PropertyTab)list[index];
936 #region ICollection Members
937 bool ICollection.IsSynchronized {
938 get {
939 return list.IsSynchronized;
943 void ICollection.CopyTo(Array array, int index) {
944 list.CopyTo(array, index);
947 object ICollection.SyncRoot {
948 get {
949 return list.SyncRoot;
953 #endregion
955 #region IEnumerable Members
956 public IEnumerator GetEnumerator() {
957 return list.GetEnumerator();
960 #endregion
962 #region ICollection Members
963 public int Count {
964 get {
965 return list.Count;
969 #endregion
971 #region Public Instance Methods
972 public void AddTabType(System.Type propertyTabType) {
973 list.Add(Activator.CreateInstance(propertyTabType));
975 [MonoTODO]
976 public void AddTabType(System.Type propertyTabType,
977 System.ComponentModel.PropertyTabScope tabScope) {
978 AddTabType(propertyTabType);
980 [MonoTODO]
981 public void Clear(System.ComponentModel.PropertyTabScope tabScope) {
982 throw new NotImplementedException();
984 [MonoTODO]
985 public void RemoveTabType(System.Type propertyTabType) {
986 throw new NotImplementedException();
988 #endregion
990 #endregion // PropertyTabCollection Class
992 #region Private Helper Methods
994 private GridItem FindFirstItem (GridItem root)
996 if (root.GridItemType == GridItemType.Property)
997 return root;
999 foreach (GridItem item in root.GridItems) {
1000 GridItem subitem = FindFirstItem (item);
1001 if (subitem != null)
1002 return subitem;
1005 return null;
1009 private void toolbar_ButtonClick (object sender, ToolBarButtonClickEventArgs e) {
1010 if (e.Button == alphabetic_toolbarbutton) {
1011 this.PropertySort = PropertySort.Alphabetical;
1013 else if (e.Button == categorized_toolbarbutton) {
1014 this.PropertySort = PropertySort.Categorized;
1018 internal void UpdateToolBarButtons () {
1019 if (PropertySort == PropertySort.Alphabetical) {
1020 categorized_toolbarbutton.Pushed = false;
1021 alphabetic_toolbarbutton.Pushed = true;
1023 else if (PropertySort == PropertySort.Categorized) {
1024 categorized_toolbarbutton.Pushed = true;
1025 alphabetic_toolbarbutton.Pushed = false;
1027 else {
1028 categorized_toolbarbutton.Pushed = false;
1029 alphabetic_toolbarbutton.Pushed = false;
1033 private void OnResetPropertyClick (object sender, EventArgs e) {
1034 ResetSelectedProperty();
1037 private void OnDescriptionClick (object sender, EventArgs e) {
1038 this.HelpVisible = !this.HelpVisible;
1039 description_menuitem.Checked = this.HelpVisible;
1043 private void ReflectObjects () {
1044 if (selected_objects.Length > 0) {
1045 root_grid_item = new RootGridEntry (property_grid_view,
1046 selected_objects.Length > 1 ? selected_objects : selected_objects[0]);
1048 PopulateMergedGridItems (selected_objects, root_grid_item.GridItems, true, root_grid_item);
1052 private void PopulateMergedGridItems (object[] objs, GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item)
1054 ArrayList intersection = null;
1056 for (int i = 0; i < objs.Length; i ++) {
1057 if (objs [i] == null)
1058 continue;
1060 ArrayList new_intersection = new ArrayList ();
1061 Type type = objs[i].GetType();
1063 /* i tried using filter attributes, but there's no way to do it for EditorBrowsableAttributes,
1064 since that type lacks an override for IsDefaultAttribute, and for some reason the
1065 BrowsableAttribute.Yes filter wasn't working */
1066 PropertyDescriptorCollection properties = null;
1068 if (typeof (ICustomTypeDescriptor).IsAssignableFrom (type)) {
1069 properties = ((ICustomTypeDescriptor)objs[i]).GetProperties ();
1071 if (properties == null) {
1072 TypeConverter cvt = TypeDescriptor.GetConverter (objs[i]);
1073 properties = cvt.GetProperties (objs[i]);
1075 if (properties == null) {
1076 properties = TypeDescriptor.GetProperties (objs[i]);
1079 foreach (PropertyDescriptor p in (i == 0 ? (ICollection)properties : (ICollection)intersection)) {
1080 PropertyDescriptor property = (i == 0 ? p : properties [p.Name]);
1081 if (property == null) {
1082 /* since the property doesn't exist in at least one of the other types,
1083 exclude it */
1085 else if (!property.IsBrowsable
1086 || (objs.Length > 1 && property.Attributes.Contains (MergablePropertyAttribute.No))
1087 || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Never))
1088 || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Advanced))) {
1089 /* if the property isn't supposed to be displayed in the merged view,
1090 excluded it */
1092 else {
1093 Type p_type = p.ComponentType;
1094 Type property_type = property.ComponentType;
1096 if (p_type.IsAssignableFrom (type))
1097 new_intersection.Add (p);
1098 else if (property_type.IsAssignableFrom (p_type))
1099 new_intersection.Add (property);
1103 intersection = new_intersection;
1106 if (intersection != null && intersection.Count > 0)
1107 PopulateGridItemsFromProperties (objs, intersection, grid_item_coll, recurse, parent_grid_item);
1110 private void PopulateGridItemsFromProperties (object[] objs, ArrayList properties,
1111 GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item) {
1112 foreach (PropertyDescriptor property in properties) {
1114 GridEntry grid_entry = new GridEntry (property_grid_view, objs, property);
1115 grid_entry.SetParent (parent_grid_item);
1116 if (property_sort == PropertySort.Alphabetical || /* XXX */property_sort == PropertySort.NoSort || !recurse) {
1117 if (grid_item_coll[property.Name] == null) {
1118 grid_item_coll.Add(property.Name,grid_entry);
1119 grid_entry.SetParent ((GridEntry)parent_grid_item);
1122 else if (property_sort == PropertySort.Categorized || property_sort == PropertySort.CategorizedAlphabetical) {
1124 string category = property.Category;
1125 CategoryGridEntry cat_item = grid_item_coll[category] as CategoryGridEntry;
1126 if (cat_item == null) {
1127 cat_item = new CategoryGridEntry (property_grid_view, category);
1128 cat_item.SetParent (parent_grid_item);
1129 grid_item_coll.Add (category, cat_item);
1131 if (cat_item.GridItems[property.Name] == null) {
1132 cat_item.GridItems.Add(property.Name,grid_entry);
1133 grid_entry.SetParent (cat_item);
1137 if (recurse && property.Converter != null && property.Converter.GetPropertiesSupported()) {
1138 object[] subobjs = new object[objs.Length];
1139 for (int i = 0; i < objs.Length; i ++)
1140 subobjs[i] = property.GetValue (objs[i]);
1141 PopulateMergedGridItems (subobjs, grid_entry.GridItems, false, grid_entry);
1143 grid_entry.Expanded = false;
1147 private void help_panel_Paint(object sender, PaintEventArgs e) {
1148 e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(help_panel.BackColor), help_panel.ClientRectangle );
1149 e.Graphics.DrawRectangle(SystemPens.ControlDark, 0,0,help_panel.Width-1,help_panel.Height-1 );
1152 internal object GetTarget (GridItem item, int selected_index)
1154 object target = ((GridEntry)item).SelectedObjects[selected_index];
1156 while (item.Parent != null && item.Parent.GridItemType != GridItemType.Property)
1157 item = item.Parent;
1159 if (item.Parent != null && item.Parent.PropertyDescriptor != null)
1160 target = item.Parent.PropertyDescriptor.GetValue (((GridEntry)item.Parent).SelectedObjects[selected_index]);
1162 return target;
1164 #endregion // Private Helper Methods
1167 #if NET_2_0
1169 [DefaultValue (false)]
1170 public bool UseCompatibleTextRendering {
1171 get {
1172 return use_compatible_text_rendering;
1175 set {
1176 use_compatible_text_rendering = value;
1179 #endif
1181 // as we can not change the color for BorderStyle.FixedSingle and we need the correct
1182 // ClientRectangle so that the ScrollBar doesn't draw over the border we need this class
1183 internal class BorderHelperControl : Control {
1185 public BorderHelperControl ()
1187 BackColor = ThemeEngine.Current.ColorWindow;
1190 protected override void OnPaint (PaintEventArgs e)
1192 e.Graphics.DrawRectangle (SystemPens.ControlDark, 0 , 0 , Width - 1, Height - 1);
1193 base.OnPaint (e);
1196 protected override void OnSizeChanged (EventArgs e)
1198 if (Controls.Count == 1) {
1199 Control control = Controls [0];
1201 if (control.Location.X != 1 || control.Location.Y != 1)
1202 control.Location = new Point (1, 1);
1204 control.Width = ClientRectangle.Width - 2;
1205 control.Height = ClientRectangle.Height - 2;
1207 base.OnSizeChanged (e);
1211 // needed! this little helper makes it possible to draw a different toolbar border
1212 // and toolbar backcolor in ThemeWin32Classic
1213 internal class PropertyToolBar : ToolBar {}
1216 [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")]
1217 internal class SelectedObjectConverter : TypeConverter