1703 lines
48 KiB
C#
1703 lines
48 KiB
C#
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||
|
// a copy of this software and associated documentation files (the
|
||
|
// "Software"), to deal in the Software without restriction, including
|
||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||
|
// the following conditions:
|
||
|
//
|
||
|
// The above copyright notice and this permission notice shall be
|
||
|
// included in all copies or substantial portions of the Software.
|
||
|
//
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
//
|
||
|
// Copyright (c) 2004-2008 Novell, Inc.
|
||
|
//
|
||
|
// Authors:
|
||
|
// Jonathan Chambers (jonathan.chambers@ansys.com)
|
||
|
// Ivan N. Zlatev (contact@i-nz.net)
|
||
|
//
|
||
|
|
||
|
// NOT COMPLETE
|
||
|
|
||
|
using System;
|
||
|
using System.IO;
|
||
|
using System.Drawing;
|
||
|
using System.Drawing.Design;
|
||
|
using System.ComponentModel;
|
||
|
using System.Collections;
|
||
|
using System.ComponentModel.Design;
|
||
|
using System.Reflection;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System.Windows.Forms.Design;
|
||
|
using System.Windows.Forms.PropertyGridInternal;
|
||
|
|
||
|
namespace System.Windows.Forms
|
||
|
{
|
||
|
[Designer("System.Windows.Forms.Design.PropertyGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
|
||
|
[ClassInterface (ClassInterfaceType.AutoDispatch)]
|
||
|
[ComVisible (true)]
|
||
|
public class PropertyGrid : System.Windows.Forms.ContainerControl, ComponentModel.Com2Interop.IComPropertyBrowser
|
||
|
{
|
||
|
#region Private Members
|
||
|
|
||
|
|
||
|
private const string UNCATEGORIZED_CATEGORY_LABEL = "Misc";
|
||
|
private AttributeCollection browsable_attributes = null;
|
||
|
private bool can_show_commands = false;
|
||
|
private Color commands_back_color;
|
||
|
private Color commands_fore_color;
|
||
|
private bool commands_visible;
|
||
|
private bool commands_visible_if_available;
|
||
|
private Point context_menu_default_location;
|
||
|
private bool large_buttons;
|
||
|
private Color line_color;
|
||
|
private PropertySort property_sort;
|
||
|
private PropertyTabCollection property_tabs;
|
||
|
private GridEntry selected_grid_item;
|
||
|
private GridEntry root_grid_item;
|
||
|
private object[] selected_objects;
|
||
|
private PropertyTab properties_tab;
|
||
|
private PropertyTab selected_tab;
|
||
|
|
||
|
private ImageList toolbar_imagelist;
|
||
|
private Image categorized_image;
|
||
|
private Image alphabetical_image;
|
||
|
private Image propertypages_image;
|
||
|
private PropertyToolBarButton categorized_toolbarbutton;
|
||
|
private PropertyToolBarButton alphabetic_toolbarbutton;
|
||
|
private PropertyToolBarButton propertypages_toolbarbutton;
|
||
|
private PropertyToolBarSeparator separator_toolbarbutton;
|
||
|
private bool events_tab_visible;
|
||
|
|
||
|
private PropertyToolBar toolbar;
|
||
|
|
||
|
private PropertyGridView property_grid_view;
|
||
|
private Splitter splitter;
|
||
|
private Panel help_panel;
|
||
|
private Label help_title_label;
|
||
|
private Label help_description_label;
|
||
|
private MenuItem reset_menuitem;
|
||
|
private MenuItem description_menuitem;
|
||
|
|
||
|
private Color category_fore_color;
|
||
|
private Color commands_active_link_color;
|
||
|
private Color commands_disabled_link_color;
|
||
|
private Color commands_link_color;
|
||
|
#endregion // Private Members
|
||
|
|
||
|
#region Contructors
|
||
|
public PropertyGrid ()
|
||
|
{
|
||
|
selected_objects = new object[0];
|
||
|
property_tabs = new PropertyTabCollection(this);
|
||
|
|
||
|
line_color = SystemColors.ScrollBar;
|
||
|
category_fore_color = line_color;
|
||
|
commands_visible = false;
|
||
|
commands_visible_if_available = false;
|
||
|
property_sort = PropertySort.CategorizedAlphabetical;
|
||
|
property_grid_view = new PropertyGridView(this);
|
||
|
|
||
|
splitter = new Splitter();
|
||
|
splitter.Dock = DockStyle.Bottom;
|
||
|
|
||
|
help_panel = new Panel();
|
||
|
help_panel.Dock = DockStyle.Bottom;
|
||
|
//help_panel.DockPadding.All = 3;
|
||
|
help_panel.Height = 50;
|
||
|
help_panel.BackColor = SystemColors.Control;
|
||
|
|
||
|
|
||
|
help_title_label = new Label();
|
||
|
help_title_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||
|
help_title_label.Name = "help_title_label";
|
||
|
help_title_label.Font = new Font(this.Font,FontStyle.Bold);
|
||
|
help_title_label.Location = new Point(2,2);
|
||
|
help_title_label.Height = 17;
|
||
|
help_title_label.Width = help_panel.Width - 4;
|
||
|
|
||
|
|
||
|
help_description_label = new Label();
|
||
|
help_description_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
|
||
|
help_description_label.AutoEllipsis = true;
|
||
|
help_description_label.AutoSize = false;
|
||
|
help_description_label.Font = this.Font;
|
||
|
help_description_label.Location = new Point(2,help_title_label.Top+help_title_label.Height);
|
||
|
help_description_label.Width = help_panel.Width - 4;
|
||
|
help_description_label.Height = help_panel.Height - help_description_label.Top - 2;
|
||
|
|
||
|
help_panel.Controls.Add(help_description_label);
|
||
|
help_panel.Controls.Add(help_title_label);
|
||
|
help_panel.Paint+=new PaintEventHandler(help_panel_Paint);
|
||
|
|
||
|
toolbar = new PropertyToolBar();
|
||
|
toolbar.Dock = DockStyle.Top;
|
||
|
categorized_toolbarbutton = new PropertyToolBarButton ();
|
||
|
categorized_toolbarbutton.Pushed = true;
|
||
|
alphabetic_toolbarbutton = new PropertyToolBarButton ();
|
||
|
propertypages_toolbarbutton = new PropertyToolBarButton ();
|
||
|
separator_toolbarbutton = new PropertyToolBarSeparator ();
|
||
|
ContextMenu context_menu = new ContextMenu();
|
||
|
context_menu_default_location = Point.Empty;
|
||
|
|
||
|
categorized_image = new Bitmap (typeof (PropertyGrid), "propertygrid-categorized.png");
|
||
|
alphabetical_image = new Bitmap (typeof (PropertyGrid), "propertygrid-alphabetical.png");
|
||
|
propertypages_image = new Bitmap (typeof (PropertyGrid), "propertygrid-propertypages.png");
|
||
|
|
||
|
toolbar_imagelist = new ImageList();
|
||
|
toolbar_imagelist.ColorDepth = ColorDepth.Depth32Bit;
|
||
|
toolbar_imagelist.ImageSize = new System.Drawing.Size(16, 16);
|
||
|
toolbar_imagelist.TransparentColor = System.Drawing.Color.Transparent;
|
||
|
|
||
|
toolbar.Appearance = ToolBarAppearance.Flat;
|
||
|
toolbar.AutoSize = false;
|
||
|
|
||
|
toolbar.ImageList = toolbar_imagelist;
|
||
|
toolbar.Location = new System.Drawing.Point(0, 0);
|
||
|
toolbar.ShowToolTips = true;
|
||
|
toolbar.Size = new System.Drawing.Size(256, 27);
|
||
|
toolbar.TabIndex = 0;
|
||
|
|
||
|
toolbar.Items.AddRange (new ToolStripItem [] {categorized_toolbarbutton,
|
||
|
alphabetic_toolbarbutton,
|
||
|
new PropertyToolBarSeparator (),
|
||
|
propertypages_toolbarbutton});
|
||
|
//toolbar.ButtonSize = new System.Drawing.Size (20, 20);
|
||
|
categorized_toolbarbutton.Click += new EventHandler (toolbarbutton_clicked);
|
||
|
alphabetic_toolbarbutton.Click += new EventHandler (toolbarbutton_clicked);
|
||
|
propertypages_toolbarbutton.Click += new EventHandler (toolbarbutton_clicked);
|
||
|
|
||
|
categorized_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
|
||
|
categorized_toolbarbutton.ToolTipText = Locale.GetText ("Categorized");
|
||
|
|
||
|
alphabetic_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
|
||
|
alphabetic_toolbarbutton.ToolTipText = Locale.GetText ("Alphabetic");
|
||
|
|
||
|
propertypages_toolbarbutton.Enabled = false;
|
||
|
propertypages_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
|
||
|
propertypages_toolbarbutton.ToolTipText = "Property Pages";
|
||
|
|
||
|
properties_tab = CreatePropertyTab (this.DefaultTabType);
|
||
|
selected_tab = properties_tab;
|
||
|
RefreshToolbar (property_tabs);
|
||
|
|
||
|
reset_menuitem = context_menu.MenuItems.Add("Reset");
|
||
|
reset_menuitem.Click +=new EventHandler(OnResetPropertyClick);
|
||
|
context_menu.MenuItems.Add("-");
|
||
|
description_menuitem = context_menu.MenuItems.Add("Description");
|
||
|
description_menuitem.Click += new EventHandler(OnDescriptionClick);
|
||
|
description_menuitem.Checked = this.HelpVisible;
|
||
|
this.ContextMenu = context_menu;
|
||
|
toolbar.ContextMenu = context_menu;
|
||
|
|
||
|
BorderHelperControl helper = new BorderHelperControl ();
|
||
|
helper.Dock = DockStyle.Fill;
|
||
|
helper.Controls.Add (property_grid_view);
|
||
|
|
||
|
this.Controls.Add(helper);
|
||
|
this.Controls.Add(toolbar);
|
||
|
this.Controls.Add(splitter);
|
||
|
this.Controls.Add(help_panel);
|
||
|
this.Name = "PropertyGrid";
|
||
|
this.Size = new System.Drawing.Size(256, 400);
|
||
|
}
|
||
|
#endregion // Constructors
|
||
|
|
||
|
#region Public Instance Properties
|
||
|
|
||
|
[BrowsableAttribute(false)]
|
||
|
[EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
|
||
|
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||
|
public AttributeCollection BrowsableAttributes {
|
||
|
get {
|
||
|
if (browsable_attributes == null) {
|
||
|
browsable_attributes = new AttributeCollection (new Attribute[] {
|
||
|
BrowsableAttribute.Yes });
|
||
|
}
|
||
|
return browsable_attributes;
|
||
|
}
|
||
|
set {
|
||
|
if (browsable_attributes == value)
|
||
|
return;
|
||
|
|
||
|
if (browsable_attributes == null || browsable_attributes.Count == 0)
|
||
|
browsable_attributes = null;
|
||
|
else
|
||
|
browsable_attributes = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public override bool AutoScroll {
|
||
|
get {
|
||
|
return base.AutoScroll;
|
||
|
}
|
||
|
set {
|
||
|
base.AutoScroll = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override Color BackColor {
|
||
|
get {
|
||
|
return base.BackColor;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
base.BackColor = value;
|
||
|
toolbar.BackColor = value;
|
||
|
Refresh ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public override Image BackgroundImage {
|
||
|
get {
|
||
|
return base.BackgroundImage;
|
||
|
}
|
||
|
set {
|
||
|
base.BackgroundImage = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
[Browsable(false)]
|
||
|
public override ImageLayout BackgroundImageLayout {
|
||
|
get { return base.BackgroundImageLayout; }
|
||
|
set { base.BackgroundImageLayout = value; }
|
||
|
}
|
||
|
|
||
|
[BrowsableAttribute(false)]
|
||
|
[EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
|
||
|
public virtual bool CanShowCommands {
|
||
|
get {
|
||
|
return can_show_commands;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue(typeof(Color), "ControlText")]
|
||
|
public Color CategoryForeColor {
|
||
|
get {
|
||
|
return category_fore_color;
|
||
|
}
|
||
|
set {
|
||
|
if (category_fore_color != value) {
|
||
|
category_fore_color = value;
|
||
|
Invalidate ();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Color CommandsBackColor {
|
||
|
get {
|
||
|
return commands_back_color;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (commands_back_color == value) {
|
||
|
return;
|
||
|
}
|
||
|
commands_back_color = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Color CommandsForeColor {
|
||
|
get {
|
||
|
return commands_fore_color;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (commands_fore_color == value) {
|
||
|
return;
|
||
|
}
|
||
|
commands_fore_color = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Color CommandsActiveLinkColor {
|
||
|
get {
|
||
|
return commands_active_link_color;
|
||
|
}
|
||
|
set {
|
||
|
commands_active_link_color = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Color CommandsDisabledLinkColor {
|
||
|
get {
|
||
|
return commands_disabled_link_color;
|
||
|
}
|
||
|
set {
|
||
|
commands_disabled_link_color = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Color CommandsLinkColor {
|
||
|
get {
|
||
|
return commands_link_color;
|
||
|
}
|
||
|
set {
|
||
|
commands_link_color = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[BrowsableAttribute (false)]
|
||
|
[EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
|
||
|
[MonoTODO ("Commands are not implemented yet.")]
|
||
|
public virtual bool CommandsVisible {
|
||
|
get {
|
||
|
return commands_visible;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue (true)]
|
||
|
public virtual bool CommandsVisibleIfAvailable {
|
||
|
get {
|
||
|
return commands_visible_if_available;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (commands_visible_if_available == value) {
|
||
|
return;
|
||
|
}
|
||
|
commands_visible_if_available = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[BrowsableAttribute(false)]
|
||
|
[EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
|
||
|
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||
|
public Point ContextMenuDefaultLocation {
|
||
|
get {
|
||
|
return context_menu_default_location;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
|
public new Control.ControlCollection Controls {
|
||
|
get {
|
||
|
return base.Controls;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public override Color ForeColor {
|
||
|
get {
|
||
|
return base.ForeColor;
|
||
|
}
|
||
|
set {
|
||
|
base.ForeColor = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("Color [Control]")]
|
||
|
public Color HelpBackColor {
|
||
|
get {
|
||
|
return help_panel.BackColor;
|
||
|
}
|
||
|
set {
|
||
|
help_panel.BackColor = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("Color [ControlText]")]
|
||
|
public Color HelpForeColor {
|
||
|
get {
|
||
|
return help_panel.ForeColor;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
help_panel.ForeColor = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue(true)]
|
||
|
[Localizable(true)]
|
||
|
public virtual bool HelpVisible {
|
||
|
get {
|
||
|
return help_panel.Visible;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
splitter.Visible = value;
|
||
|
help_panel.Visible = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue (false)]
|
||
|
public bool LargeButtons {
|
||
|
get {
|
||
|
return large_buttons;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (large_buttons == value) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
large_buttons = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("Color [InactiveBorder]")]
|
||
|
public Color LineColor {
|
||
|
get {
|
||
|
return line_color;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (line_color == value) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
line_color = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
[Browsable(false)]
|
||
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
|
public new Padding Padding {
|
||
|
get { return base.Padding; }
|
||
|
set { base.Padding = value; }
|
||
|
}
|
||
|
|
||
|
[DefaultValue(PropertySort.CategorizedAlphabetical)]
|
||
|
public PropertySort PropertySort {
|
||
|
get {
|
||
|
return property_sort;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (!Enum.IsDefined (typeof (PropertySort), value))
|
||
|
throw new InvalidEnumArgumentException ("value", (int) value, typeof (PropertySort));
|
||
|
if (property_sort == value)
|
||
|
return;
|
||
|
|
||
|
// we do not need to update the the grid items and fire
|
||
|
// a PropertySortChanged event when switching between
|
||
|
// Categorized and CateogizedAlphabetical
|
||
|
bool needUpdate = (property_sort & PropertySort.Categorized) == 0 ||
|
||
|
(value & PropertySort.Categorized) == 0;
|
||
|
property_sort = value;
|
||
|
if (needUpdate) {
|
||
|
UpdateSortLayout (root_grid_item);
|
||
|
// update selection
|
||
|
if (selected_grid_item != null) {
|
||
|
if (selected_grid_item.GridItemType == GridItemType.Category &&
|
||
|
(value == PropertySort.Alphabetical || value == PropertySort.NoSort))
|
||
|
SelectItemCore (null, null);
|
||
|
else
|
||
|
SelectItemCore (null, selected_grid_item);
|
||
|
}
|
||
|
property_grid_view.UpdateView ();
|
||
|
|
||
|
EventHandler eh = (EventHandler)(Events [PropertySortChangedEvent]);
|
||
|
if (eh != null)
|
||
|
eh (this, EventArgs.Empty);
|
||
|
}
|
||
|
UpdatePropertySortButtonsState ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[BrowsableAttribute(false)]
|
||
|
[EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
|
||
|
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||
|
public PropertyTabCollection PropertyTabs {
|
||
|
get { return property_tabs; }
|
||
|
}
|
||
|
|
||
|
[BrowsableAttribute(false)]
|
||
|
[EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
|
||
|
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||
|
public GridItem SelectedGridItem {
|
||
|
get { return selected_grid_item; }
|
||
|
set {
|
||
|
if (value == null)
|
||
|
throw new ArgumentException ("GridItem specified to PropertyGrid.SelectedGridItem must be a valid GridItem.");
|
||
|
if (value != selected_grid_item) {
|
||
|
GridEntry oldItem = selected_grid_item;
|
||
|
SelectItemCore (oldItem, (GridEntry)value);
|
||
|
OnSelectedGridItemChanged (new SelectedGridItemChangedEventArgs (oldItem, value));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal GridItem RootGridItem {
|
||
|
get { return root_grid_item; }
|
||
|
}
|
||
|
|
||
|
private void UpdateHelp (GridItem item)
|
||
|
{
|
||
|
if (item == null) {
|
||
|
help_title_label.Text = string.Empty;
|
||
|
help_description_label.Text = string.Empty;
|
||
|
} else {
|
||
|
help_title_label.Text = item.Label;
|
||
|
if (item.PropertyDescriptor != null)
|
||
|
this.help_description_label.Text = item.PropertyDescriptor.Description;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void SelectItemCore (GridEntry oldItem, GridEntry item)
|
||
|
{
|
||
|
UpdateHelp (item);
|
||
|
selected_grid_item = item;
|
||
|
property_grid_view.SelectItem (oldItem, item);
|
||
|
}
|
||
|
|
||
|
internal void OnPropertyValueChangedInternal (GridItem item, object property_value)
|
||
|
{
|
||
|
property_grid_view.UpdateView ();
|
||
|
OnPropertyValueChanged (new PropertyValueChangedEventArgs (item, property_value));
|
||
|
}
|
||
|
|
||
|
internal void OnExpandItem (GridEntry item)
|
||
|
{
|
||
|
property_grid_view.ExpandItem (item);
|
||
|
}
|
||
|
|
||
|
internal void OnCollapseItem (GridEntry item)
|
||
|
{
|
||
|
property_grid_view.CollapseItem (item);
|
||
|
}
|
||
|
|
||
|
internal DialogResult ShowError (string text)
|
||
|
{
|
||
|
return this.ShowError (text, MessageBoxButtons.OK);
|
||
|
}
|
||
|
|
||
|
internal DialogResult ShowError (string text, MessageBoxButtons buttons)
|
||
|
{
|
||
|
if (text == null)
|
||
|
throw new ArgumentNullException ("text");
|
||
|
return MessageBox.Show (this, text, "Properties Window", buttons, MessageBoxIcon.Exclamation);
|
||
|
}
|
||
|
|
||
|
[DefaultValue(null)]
|
||
|
[TypeConverter("System.Windows.Forms.PropertyGrid+SelectedObjectConverter, " + Consts.AssemblySystem_Windows_Forms)]
|
||
|
public object SelectedObject {
|
||
|
get {
|
||
|
if (selected_objects.Length > 0)
|
||
|
return selected_objects[0];
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
if (selected_objects != null && selected_objects.Length == 1 && selected_objects[0] == value)
|
||
|
return;
|
||
|
if (value == null)
|
||
|
SelectedObjects = new object[0];
|
||
|
else
|
||
|
SelectedObjects = new object[] {value};
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[BrowsableAttribute(false)]
|
||
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
|
public object[] SelectedObjects {
|
||
|
get {
|
||
|
return selected_objects;
|
||
|
}
|
||
|
|
||
|
set {
|
||
|
root_grid_item = null;
|
||
|
SelectItemCore (null, null); // unselect current item in the view
|
||
|
if (value != null) {
|
||
|
for (int i = 0; i < value.Length; i++) {
|
||
|
if (value [i] == null)
|
||
|
throw new ArgumentException (String.Format ("Item {0} in the objs array is null.", i));
|
||
|
}
|
||
|
selected_objects = value;
|
||
|
} else {
|
||
|
selected_objects = new object [0];
|
||
|
}
|
||
|
|
||
|
ShowEventsButton (false);
|
||
|
PopulateGrid (selected_objects);
|
||
|
RefreshTabs(PropertyTabScope.Component);
|
||
|
if (root_grid_item != null)
|
||
|
SelectItemCore (null, GetDefaultPropertyItem (root_grid_item, selected_tab));
|
||
|
property_grid_view.UpdateView ();
|
||
|
OnSelectedObjectsChanged (EventArgs.Empty);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[BrowsableAttribute(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||
|
public PropertyTab SelectedTab {
|
||
|
get { return selected_tab; }
|
||
|
}
|
||
|
|
||
|
public override ISite Site {
|
||
|
get { return base.Site; }
|
||
|
set { base.Site = value; }
|
||
|
}
|
||
|
|
||
|
[Browsable (false)]
|
||
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
||
|
public override string Text {
|
||
|
get { return base.Text; }
|
||
|
set { base.Text = value; }
|
||
|
}
|
||
|
|
||
|
[DefaultValue(true)]
|
||
|
public virtual bool ToolbarVisible {
|
||
|
get { return toolbar.Visible; }
|
||
|
set {
|
||
|
if (toolbar.Visible == value) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
toolbar.Visible = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected ToolStripRenderer ToolStripRenderer {
|
||
|
get {
|
||
|
if (toolbar != null) {
|
||
|
return toolbar.Renderer;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
set {
|
||
|
if (toolbar != null) {
|
||
|
toolbar.Renderer = value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("Color [Window]")]
|
||
|
public Color ViewBackColor {
|
||
|
get { return property_grid_view.BackColor; }
|
||
|
set {
|
||
|
if (property_grid_view.BackColor == value) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
property_grid_view.BackColor = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue ("Color [WindowText]")]
|
||
|
public Color ViewForeColor {
|
||
|
get { return property_grid_view.ForeColor; }
|
||
|
set {
|
||
|
if (property_grid_view.ForeColor == value) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
property_grid_view.ForeColor = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[DefaultValue (false)]
|
||
|
public bool UseCompatibleTextRendering {
|
||
|
get { return use_compatible_text_rendering; }
|
||
|
set {
|
||
|
if (use_compatible_text_rendering != value) {
|
||
|
use_compatible_text_rendering = value;
|
||
|
if (Parent != null)
|
||
|
Parent.PerformLayout (this, "UseCompatibleTextRendering");
|
||
|
Invalidate ();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion // Public Instance Properties
|
||
|
|
||
|
#region Protected Instance Properties
|
||
|
|
||
|
protected override Size DefaultSize {
|
||
|
get { return base.DefaultSize; }
|
||
|
}
|
||
|
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||
|
protected virtual Type DefaultTabType {
|
||
|
get { return typeof(PropertiesTab); }
|
||
|
}
|
||
|
|
||
|
protected bool DrawFlatToolbar {
|
||
|
get { return (toolbar.Appearance == ToolBarAppearance.Flat); }
|
||
|
set {
|
||
|
if (value)
|
||
|
toolbar.Appearance = ToolBarAppearance.Flat;
|
||
|
else
|
||
|
toolbar.Appearance = ToolBarAppearance.Normal;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected internal override bool ShowFocusCues {
|
||
|
get { return base.ShowFocusCues; }
|
||
|
}
|
||
|
|
||
|
#endregion // Protected Instance Properties
|
||
|
|
||
|
#region Public Instance Methods
|
||
|
|
||
|
protected override void Dispose(bool disposing) {
|
||
|
base.Dispose(disposing);
|
||
|
}
|
||
|
|
||
|
public void CollapseAllGridItems ()
|
||
|
{
|
||
|
GridEntry category = FindCategoryItem (selected_grid_item);
|
||
|
if (category != null)
|
||
|
SelectedGridItem = category;
|
||
|
CollapseItemRecursive (root_grid_item);
|
||
|
property_grid_view.UpdateView ();
|
||
|
}
|
||
|
|
||
|
private void CollapseItemRecursive (GridItem item)
|
||
|
{
|
||
|
if (item == null)
|
||
|
return;
|
||
|
|
||
|
foreach (GridItem child in item.GridItems) {
|
||
|
CollapseItemRecursive (child);
|
||
|
if (child.Expandable)
|
||
|
child.Expanded = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private GridEntry FindCategoryItem (GridEntry entry)
|
||
|
{
|
||
|
if (entry == null || (property_sort != PropertySort.Categorized &&
|
||
|
property_sort != PropertySort.CategorizedAlphabetical))
|
||
|
return null;
|
||
|
|
||
|
if (entry.GridItemType == GridItemType.Category)
|
||
|
return entry;
|
||
|
|
||
|
GridEntry category = null;
|
||
|
GridItem current = (GridItem)entry;
|
||
|
while (category == null) {
|
||
|
if (current.Parent != null && current.Parent.GridItemType == GridItemType.Category)
|
||
|
category = (GridEntry) current.Parent;
|
||
|
current = current.Parent;
|
||
|
if (current == null)
|
||
|
break;
|
||
|
}
|
||
|
return (GridEntry) category;
|
||
|
}
|
||
|
|
||
|
public void ExpandAllGridItems ()
|
||
|
{
|
||
|
ExpandItemRecursive (root_grid_item);
|
||
|
property_grid_view.UpdateView ();
|
||
|
}
|
||
|
|
||
|
private void ExpandItemRecursive (GridItem item)
|
||
|
{
|
||
|
if (item == null)
|
||
|
return;
|
||
|
|
||
|
foreach (GridItem child in item.GridItems) {
|
||
|
ExpandItemRecursive (child);
|
||
|
if (child.Expandable)
|
||
|
child.Expanded = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void Refresh ()
|
||
|
{
|
||
|
base.Refresh ();
|
||
|
// force a full reload here
|
||
|
SelectedObjects = SelectedObjects;
|
||
|
}
|
||
|
|
||
|
private void toolbar_Clicked (PropertyToolBarButton button)
|
||
|
{
|
||
|
if (button == null)
|
||
|
return;
|
||
|
|
||
|
if (button == alphabetic_toolbarbutton) {
|
||
|
this.PropertySort = PropertySort.Alphabetical;
|
||
|
alphabetic_toolbarbutton.Pushed = true;
|
||
|
categorized_toolbarbutton.Pushed = false;
|
||
|
} else if (button == categorized_toolbarbutton) {
|
||
|
this.PropertySort = PropertySort.CategorizedAlphabetical;
|
||
|
categorized_toolbarbutton.Pushed = true;
|
||
|
alphabetic_toolbarbutton.Pushed = false;
|
||
|
} else {
|
||
|
if (button.Enabled)
|
||
|
SelectPropertyTab (button.PropertyTab);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void toolbarbutton_clicked (object o, EventArgs args)
|
||
|
{
|
||
|
toolbar_Clicked (o as PropertyToolBarButton);
|
||
|
}
|
||
|
|
||
|
private void SelectPropertyTab (PropertyTab propertyTab)
|
||
|
{
|
||
|
if (propertyTab != null && selected_tab != propertyTab) {
|
||
|
foreach (object toolbarItem in toolbar.Items) {
|
||
|
PropertyToolBarButton button = toolbarItem as PropertyToolBarButton;
|
||
|
if (button != null && button.PropertyTab != null) {
|
||
|
if (button.PropertyTab == selected_tab)
|
||
|
button.Pushed = false;
|
||
|
else if (button.PropertyTab == propertyTab)
|
||
|
button.Pushed = true;
|
||
|
}
|
||
|
}
|
||
|
selected_tab = propertyTab;
|
||
|
PopulateGrid (selected_objects);
|
||
|
SelectItemCore (null, GetDefaultPropertyItem (root_grid_item, selected_tab));
|
||
|
property_grid_view.UpdateView ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void UpdatePropertySortButtonsState ()
|
||
|
{
|
||
|
if (property_sort == PropertySort.NoSort) {
|
||
|
alphabetic_toolbarbutton.Pushed = false;
|
||
|
categorized_toolbarbutton.Pushed = false;
|
||
|
} else if (property_sort == PropertySort.Alphabetical) {
|
||
|
alphabetic_toolbarbutton.Pushed = true;
|
||
|
categorized_toolbarbutton.Pushed = false;
|
||
|
} else if (property_sort == PropertySort.Categorized ||
|
||
|
property_sort == PropertySort.CategorizedAlphabetical) {
|
||
|
alphabetic_toolbarbutton.Pushed = false;
|
||
|
categorized_toolbarbutton.Pushed = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected void ShowEventsButton (bool value)
|
||
|
{
|
||
|
if (value && property_tabs.Contains (typeof (EventsTab)))
|
||
|
events_tab_visible = true;
|
||
|
else
|
||
|
events_tab_visible = false;
|
||
|
RefreshTabs (PropertyTabScope.Component);
|
||
|
}
|
||
|
|
||
|
public void RefreshTabs (PropertyTabScope tabScope)
|
||
|
{
|
||
|
property_tabs.Clear (tabScope);
|
||
|
if (selected_objects != null) {
|
||
|
Type[] tabTypes = null;
|
||
|
PropertyTabScope[] tabScopes = null;
|
||
|
|
||
|
if (events_tab_visible && property_tabs.Contains (typeof (EventsTab)))
|
||
|
property_tabs.InsertTab (0, properties_tab, PropertyTabScope.Component);
|
||
|
|
||
|
GetMergedPropertyTabs (selected_objects, out tabTypes, out tabScopes);
|
||
|
if (tabTypes != null && tabScopes != null && tabTypes.Length > 0) {
|
||
|
bool selectedTabPreserved = false;
|
||
|
for (int i=0; i < tabTypes.Length; i++) {
|
||
|
property_tabs.AddTabType (tabTypes[i], tabScopes[i]);
|
||
|
if (tabTypes[i] == selected_tab.GetType ())
|
||
|
selectedTabPreserved = true;
|
||
|
}
|
||
|
if (!selectedTabPreserved)
|
||
|
SelectPropertyTab (properties_tab);
|
||
|
}
|
||
|
} else {
|
||
|
SelectPropertyTab (properties_tab);
|
||
|
}
|
||
|
RefreshToolbar (property_tabs);
|
||
|
}
|
||
|
|
||
|
private void RefreshToolbar (PropertyTabCollection tabs)
|
||
|
{
|
||
|
EnsurePropertiesTab ();
|
||
|
|
||
|
toolbar.SuspendLayout ();
|
||
|
toolbar.Items.Clear ();
|
||
|
toolbar_imagelist.Images.Clear ();
|
||
|
|
||
|
int imageIndex = 0;
|
||
|
toolbar.Items.Add (categorized_toolbarbutton);
|
||
|
toolbar_imagelist.Images.Add (categorized_image);
|
||
|
categorized_toolbarbutton.ImageIndex = imageIndex;
|
||
|
imageIndex++;
|
||
|
toolbar.Items.Add (alphabetic_toolbarbutton);
|
||
|
toolbar_imagelist.Images.Add (alphabetical_image);
|
||
|
alphabetic_toolbarbutton.ImageIndex = imageIndex;
|
||
|
imageIndex++;
|
||
|
toolbar.Items.Add (separator_toolbarbutton);
|
||
|
if (tabs != null && tabs.Count > 0) {
|
||
|
foreach (PropertyTab tab in tabs) {
|
||
|
PropertyToolBarButton button = new PropertyToolBarButton (tab);
|
||
|
toolbar.Items.Add (button);
|
||
|
if (tab.Bitmap != null) {
|
||
|
tab.Bitmap.MakeTransparent ();
|
||
|
toolbar_imagelist.Images.Add (tab.Bitmap);
|
||
|
button.ImageIndex = imageIndex;
|
||
|
imageIndex++;
|
||
|
}
|
||
|
if (tab == selected_tab)
|
||
|
button.Pushed = true;
|
||
|
}
|
||
|
toolbar.Items.Add (new PropertyToolBarSeparator ());
|
||
|
}
|
||
|
|
||
|
toolbar.Items.Add (propertypages_toolbarbutton);
|
||
|
toolbar_imagelist.Images.Add (propertypages_image);
|
||
|
propertypages_toolbarbutton.ImageIndex = imageIndex;
|
||
|
|
||
|
toolbar.ResumeLayout ();
|
||
|
}
|
||
|
|
||
|
private void EnsurePropertiesTab ()
|
||
|
{
|
||
|
if (property_tabs == null)
|
||
|
return;
|
||
|
|
||
|
if (property_tabs.Count > 0 && !property_tabs.Contains (this.DefaultTabType))
|
||
|
property_tabs.InsertTab (0, properties_tab, PropertyTabScope.Component);
|
||
|
}
|
||
|
|
||
|
private void GetMergedPropertyTabs (object[] objects, out Type[] tabTypes, out PropertyTabScope[] tabScopes)
|
||
|
{
|
||
|
tabTypes = null;
|
||
|
tabScopes = null;
|
||
|
if (objects == null || objects.Length == 0)
|
||
|
return;
|
||
|
|
||
|
ArrayList intersection = null;
|
||
|
ArrayList scopes = new ArrayList ();
|
||
|
for (int i=0; i < objects.Length; i++) {
|
||
|
if (objects[i] == null)
|
||
|
continue;
|
||
|
PropertyTabAttribute tabAttribute = (PropertyTabAttribute)TypeDescriptor.GetAttributes (objects[i])[typeof (PropertyTabAttribute)];
|
||
|
if (tabAttribute == null || tabAttribute.TabClasses == null || tabAttribute.TabClasses.Length == 0)
|
||
|
return;
|
||
|
|
||
|
ArrayList new_intersection = new ArrayList ();
|
||
|
scopes.Clear ();
|
||
|
IList currentIntersection = (i == 0 ? (IList)tabAttribute.TabClasses : (IList)intersection);
|
||
|
for (int j=0; j < currentIntersection.Count; j++) {
|
||
|
if ((Type)intersection[j] == tabAttribute.TabClasses[j]) {
|
||
|
new_intersection.Add (tabAttribute.TabClasses[j]);
|
||
|
scopes.Add (tabAttribute.TabScopes[j]);
|
||
|
}
|
||
|
}
|
||
|
intersection = new_intersection;
|
||
|
}
|
||
|
|
||
|
tabTypes = new Type[intersection.Count];
|
||
|
intersection.CopyTo (tabTypes);
|
||
|
tabScopes = new PropertyTabScope[tabTypes.Length];
|
||
|
scopes.CopyTo (tabScopes);
|
||
|
}
|
||
|
|
||
|
public void ResetSelectedProperty()
|
||
|
{
|
||
|
if (selected_grid_item == null)
|
||
|
return;
|
||
|
selected_grid_item.ResetValue ();
|
||
|
}
|
||
|
#endregion // Public Instance Methods
|
||
|
|
||
|
#region Protected Instance Methods
|
||
|
|
||
|
protected virtual PropertyTab CreatePropertyTab (Type tabType)
|
||
|
{
|
||
|
if (!typeof(PropertyTab).IsAssignableFrom (tabType))
|
||
|
return null;
|
||
|
|
||
|
PropertyTab tab = null;
|
||
|
|
||
|
ConstructorInfo ctor = tabType.GetConstructor (new Type[] { typeof (IServiceProvider) });
|
||
|
if (ctor != null)
|
||
|
tab = (PropertyTab)ctor.Invoke (new object[] { this.Site });
|
||
|
else
|
||
|
tab = (PropertyTab)Activator.CreateInstance (tabType);
|
||
|
return tab;
|
||
|
}
|
||
|
|
||
|
[MonoTODO ("Never called")]
|
||
|
protected void OnComComponentNameChanged(ComponentRenameEventArgs e)
|
||
|
{
|
||
|
ComponentRenameEventHandler eh = (ComponentRenameEventHandler)(Events [ComComponentNameChangedEvent]);
|
||
|
if (eh != null)
|
||
|
eh (this, e);
|
||
|
}
|
||
|
|
||
|
protected override void OnEnabledChanged (EventArgs e) {
|
||
|
base.OnEnabledChanged (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnFontChanged(EventArgs e) {
|
||
|
base.OnFontChanged (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnGotFocus(EventArgs e) {
|
||
|
base.OnGotFocus(e);
|
||
|
}
|
||
|
|
||
|
protected override void OnHandleCreated (EventArgs e) {
|
||
|
base.OnHandleCreated (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnHandleDestroyed (EventArgs e) {
|
||
|
base.OnHandleDestroyed (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnMouseDown (MouseEventArgs me) {
|
||
|
base.OnMouseDown (me);
|
||
|
}
|
||
|
|
||
|
protected override void OnMouseMove (MouseEventArgs me) {
|
||
|
base.OnMouseMove (me);
|
||
|
}
|
||
|
|
||
|
protected override void OnMouseUp (MouseEventArgs me) {
|
||
|
base.OnMouseUp (me);
|
||
|
}
|
||
|
|
||
|
protected void OnNotifyPropertyValueUIItemsChanged(object sender, EventArgs e)
|
||
|
{
|
||
|
property_grid_view.UpdateView ();
|
||
|
}
|
||
|
|
||
|
protected override void OnPaint (PaintEventArgs pevent) {
|
||
|
pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
|
||
|
base.OnPaint (pevent);
|
||
|
}
|
||
|
|
||
|
protected virtual void OnPropertySortChanged(EventArgs e) {
|
||
|
EventHandler eh = (EventHandler) Events [PropertySortChangedEvent];
|
||
|
if (eh != null)
|
||
|
eh (this, e);
|
||
|
}
|
||
|
|
||
|
protected virtual void OnPropertyTabChanged (PropertyTabChangedEventArgs e)
|
||
|
{
|
||
|
PropertyTabChangedEventHandler eh = (PropertyTabChangedEventHandler)(Events [PropertyTabChangedEvent]);
|
||
|
if (eh != null)
|
||
|
eh (this, e);
|
||
|
}
|
||
|
|
||
|
protected virtual void OnPropertyValueChanged (PropertyValueChangedEventArgs e) {
|
||
|
PropertyValueChangedEventHandler eh = (PropertyValueChangedEventHandler)(Events [PropertyValueChangedEvent]);
|
||
|
if (eh != null)
|
||
|
eh (this, e);
|
||
|
}
|
||
|
|
||
|
protected override void OnResize (EventArgs e) {
|
||
|
base.OnResize (e);
|
||
|
}
|
||
|
|
||
|
protected virtual void OnSelectedGridItemChanged (SelectedGridItemChangedEventArgs e) {
|
||
|
SelectedGridItemChangedEventHandler eh = (SelectedGridItemChangedEventHandler)(Events [SelectedGridItemChangedEvent]);
|
||
|
if (eh != null)
|
||
|
eh (this, e);
|
||
|
}
|
||
|
|
||
|
protected virtual void OnSelectedObjectsChanged (EventArgs e) {
|
||
|
EventHandler eh = (EventHandler)(Events [SelectedObjectsChangedEvent]);
|
||
|
if (eh != null)
|
||
|
eh (this, e);
|
||
|
}
|
||
|
|
||
|
protected override void OnSystemColorsChanged (EventArgs e) {
|
||
|
base.OnSystemColorsChanged (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnVisibleChanged (EventArgs e) {
|
||
|
base.OnVisibleChanged (e);
|
||
|
}
|
||
|
|
||
|
protected override bool ProcessDialogKey (Keys keyData) {
|
||
|
return base.ProcessDialogKey (keyData);
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
||
|
protected override void ScaleCore (float dx, float dy) {
|
||
|
base.ScaleCore (dx, dy);
|
||
|
}
|
||
|
|
||
|
protected override void WndProc (ref Message m)
|
||
|
{
|
||
|
base.WndProc (ref m);
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
#region Events
|
||
|
static object PropertySortChangedEvent = new object ();
|
||
|
static object PropertyTabChangedEvent = new object ();
|
||
|
static object PropertyValueChangedEvent = new object ();
|
||
|
static object SelectedGridItemChangedEvent = new object ();
|
||
|
static object SelectedObjectsChangedEvent = new object ();
|
||
|
|
||
|
public event EventHandler PropertySortChanged {
|
||
|
add { Events.AddHandler (PropertySortChangedEvent, value); }
|
||
|
remove { Events.RemoveHandler (PropertySortChangedEvent, value); }
|
||
|
}
|
||
|
|
||
|
public event PropertyTabChangedEventHandler PropertyTabChanged {
|
||
|
add { Events.AddHandler (PropertyTabChangedEvent, value); }
|
||
|
remove { Events.RemoveHandler (PropertyTabChangedEvent, value); }
|
||
|
}
|
||
|
|
||
|
public event PropertyValueChangedEventHandler PropertyValueChanged {
|
||
|
add { Events.AddHandler (PropertyValueChangedEvent, value); }
|
||
|
remove { Events.RemoveHandler (PropertyValueChangedEvent, value); }
|
||
|
}
|
||
|
|
||
|
public event SelectedGridItemChangedEventHandler SelectedGridItemChanged {
|
||
|
add { Events.AddHandler (SelectedGridItemChangedEvent, value); }
|
||
|
remove { Events.RemoveHandler (SelectedGridItemChangedEvent, value); }
|
||
|
}
|
||
|
|
||
|
public event EventHandler SelectedObjectsChanged {
|
||
|
add { Events.AddHandler (SelectedObjectsChangedEvent, value); }
|
||
|
remove { Events.RemoveHandler (SelectedObjectsChangedEvent, value); }
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public new event EventHandler BackgroundImageChanged {
|
||
|
add { base.BackgroundImageChanged += value; }
|
||
|
remove { base.BackgroundImageChanged -= value; }
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public new event EventHandler BackgroundImageLayoutChanged {
|
||
|
add { base.BackgroundImageLayoutChanged += value; }
|
||
|
remove { base.BackgroundImageLayoutChanged -= value; }
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public new event EventHandler ForeColorChanged {
|
||
|
add { base.ForeColorChanged += value; }
|
||
|
remove { base.ForeColorChanged -= value; }
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[Browsable(false)]
|
||
|
public new event KeyEventHandler KeyDown {
|
||
|
add { base.KeyDown += value; }
|
||
|
remove { base.KeyDown -= value; }
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
public new event KeyPressEventHandler KeyPress {
|
||
|
add { base.KeyPress += value; }
|
||
|
remove { base.KeyPress -= value; }
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[Browsable(false)]
|
||
|
public new event KeyEventHandler KeyUp {
|
||
|
add { base.KeyUp += value; }
|
||
|
remove { base.KeyUp -= value; }
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
public new event MouseEventHandler MouseDown {
|
||
|
add { base.MouseDown += value; }
|
||
|
remove { base.MouseDown -= value; }
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[Browsable(false)]
|
||
|
public new event EventHandler MouseEnter {
|
||
|
add { base.MouseEnter += value; }
|
||
|
remove { base.MouseEnter -= value; }
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[Browsable(false)]
|
||
|
public new event EventHandler MouseLeave {
|
||
|
add { base.MouseLeave += value; }
|
||
|
remove { base.MouseLeave -= value; }
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[Browsable(false)]
|
||
|
public new event MouseEventHandler MouseMove {
|
||
|
add { base.MouseMove += value; }
|
||
|
remove { base.MouseMove -= value; }
|
||
|
}
|
||
|
|
||
|
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||
|
[Browsable(false)]
|
||
|
public new event MouseEventHandler MouseUp {
|
||
|
add { base.MouseUp += value; }
|
||
|
remove { base.MouseUp -= value; }
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public new event EventHandler PaddingChanged {
|
||
|
add { base.PaddingChanged += value; }
|
||
|
remove { base.PaddingChanged -= value; }
|
||
|
}
|
||
|
|
||
|
[Browsable(false)]
|
||
|
public new event EventHandler TextChanged {
|
||
|
add { base.TextChanged += value; }
|
||
|
remove { base.TextChanged -= value; }
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
#region Com2Interop.IComPropertyBrowser Interface
|
||
|
[MonoTODO ("Not implemented, will throw NotImplementedException")]
|
||
|
bool ComponentModel.Com2Interop.IComPropertyBrowser.InPropertySet {
|
||
|
get {
|
||
|
throw new NotImplementedException();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[MonoTODO ("Stub, does nothing")]
|
||
|
void ComponentModel.Com2Interop.IComPropertyBrowser.DropDownDone ()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
[MonoTODO ("Not implemented, will throw NotImplementedException")]
|
||
|
bool ComponentModel.Com2Interop.IComPropertyBrowser.EnsurePendingChangesCommitted ()
|
||
|
{
|
||
|
throw new NotImplementedException ();
|
||
|
}
|
||
|
|
||
|
[MonoTODO ("Stub, does nothing")]
|
||
|
void ComponentModel.Com2Interop.IComPropertyBrowser.HandleF4 ()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
[MonoTODO ("Stub, does nothing")]
|
||
|
void ComponentModel.Com2Interop.IComPropertyBrowser.LoadState (Microsoft.Win32.RegistryKey optRoot)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
[MonoTODO ("Stub, does nothing")]
|
||
|
void ComponentModel.Com2Interop.IComPropertyBrowser.SaveState (Microsoft.Win32.RegistryKey optRoot)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
static object ComComponentNameChangedEvent = new object ();
|
||
|
event ComponentRenameEventHandler ComponentModel.Com2Interop.IComPropertyBrowser.ComComponentNameChanged {
|
||
|
add { Events.AddHandler (ComComponentNameChangedEvent, value); }
|
||
|
remove { Events.RemoveHandler (ComComponentNameChangedEvent, value); }
|
||
|
}
|
||
|
#endregion // Com2Interop.IComPropertyBrowser Interface
|
||
|
|
||
|
#region PropertyTabCollection Class
|
||
|
public class PropertyTabCollection : ICollection, IEnumerable
|
||
|
{
|
||
|
ArrayList property_tabs;
|
||
|
ArrayList property_tabs_scopes;
|
||
|
PropertyGrid property_grid;
|
||
|
|
||
|
internal PropertyTabCollection (PropertyGrid propertyGrid)
|
||
|
{
|
||
|
property_grid = propertyGrid;
|
||
|
property_tabs = new ArrayList ();
|
||
|
property_tabs_scopes = new ArrayList ();
|
||
|
}
|
||
|
|
||
|
public PropertyTab this[int index] {
|
||
|
get { return (PropertyTab)property_tabs[index]; }
|
||
|
}
|
||
|
|
||
|
bool ICollection.IsSynchronized {
|
||
|
get { return property_tabs.IsSynchronized; }
|
||
|
}
|
||
|
|
||
|
void ICollection.CopyTo (Array dest, int index)
|
||
|
{
|
||
|
property_tabs.CopyTo (dest, index);
|
||
|
}
|
||
|
|
||
|
object ICollection.SyncRoot {
|
||
|
get { return property_tabs.SyncRoot; }
|
||
|
}
|
||
|
|
||
|
public IEnumerator GetEnumerator ()
|
||
|
{
|
||
|
return property_tabs.GetEnumerator ();
|
||
|
}
|
||
|
|
||
|
public int Count {
|
||
|
get { return property_tabs.Count; }
|
||
|
}
|
||
|
|
||
|
public void AddTabType (Type propertyTabType)
|
||
|
{
|
||
|
AddTabType (propertyTabType, PropertyTabScope.Global);
|
||
|
}
|
||
|
|
||
|
public void AddTabType (Type propertyTabType, PropertyTabScope tabScope)
|
||
|
{
|
||
|
if (propertyTabType == null)
|
||
|
throw new ArgumentNullException ("propertyTabType");
|
||
|
|
||
|
// Avoid duplicates
|
||
|
if (this.Contains (propertyTabType))
|
||
|
return;
|
||
|
PropertyTab tab = property_grid.CreatePropertyTab (propertyTabType);
|
||
|
if (tab != null) {
|
||
|
property_tabs.Add (tab);
|
||
|
property_tabs_scopes.Add (tabScope);
|
||
|
}
|
||
|
property_grid.RefreshToolbar (this);
|
||
|
}
|
||
|
|
||
|
internal PropertyTabScope GetTabScope (PropertyTab tab)
|
||
|
{
|
||
|
if (tab == null)
|
||
|
throw new ArgumentNullException ("tab");
|
||
|
|
||
|
int index = property_tabs.IndexOf (tab);
|
||
|
if (index != -1)
|
||
|
return (PropertyTabScope)property_tabs_scopes[index];
|
||
|
return PropertyTabScope.Global;
|
||
|
}
|
||
|
|
||
|
internal void InsertTab (int index, PropertyTab propertyTab, PropertyTabScope tabScope)
|
||
|
{
|
||
|
if (propertyTab == null)
|
||
|
throw new ArgumentNullException ("propertyTab");
|
||
|
|
||
|
if (!this.Contains (propertyTab.GetType ())) {
|
||
|
property_tabs.Insert (index, propertyTab);
|
||
|
property_tabs_scopes.Insert (index, tabScope);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal bool Contains (Type propertyType)
|
||
|
{
|
||
|
if (propertyType == null)
|
||
|
throw new ArgumentNullException ("propertyType");
|
||
|
|
||
|
foreach (PropertyTab t in property_tabs) {
|
||
|
if (t.GetType () == propertyType)
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
internal PropertyTab this[Type tabType] {
|
||
|
get {
|
||
|
foreach (PropertyTab tab in property_tabs) {
|
||
|
if (tabType == tab.GetType ())
|
||
|
return tab;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Clear (PropertyTabScope tabScope)
|
||
|
{
|
||
|
ArrayList toRemove = new ArrayList ();
|
||
|
for (int i=0; i < property_tabs_scopes.Count; i++) {
|
||
|
if ((PropertyTabScope)property_tabs_scopes[i] == tabScope)
|
||
|
toRemove.Add (i);
|
||
|
}
|
||
|
foreach (int indexToRemove in toRemove) {
|
||
|
property_tabs.RemoveAt (indexToRemove);
|
||
|
property_tabs_scopes.RemoveAt (indexToRemove);
|
||
|
}
|
||
|
property_grid.RefreshToolbar (this);
|
||
|
}
|
||
|
|
||
|
public void RemoveTabType (Type propertyTabType)
|
||
|
{
|
||
|
if (propertyTabType == null)
|
||
|
throw new ArgumentNullException ("propertyTabType");
|
||
|
|
||
|
ArrayList toRemove = new ArrayList ();
|
||
|
for (int i=0; i < property_tabs.Count; i++) {
|
||
|
if (property_tabs[i].GetType () == propertyTabType)
|
||
|
toRemove.Add (i);
|
||
|
}
|
||
|
foreach (int indexToRemove in toRemove) {
|
||
|
property_tabs.RemoveAt (indexToRemove);
|
||
|
property_tabs_scopes.RemoveAt (indexToRemove);
|
||
|
}
|
||
|
property_grid.RefreshToolbar (this);
|
||
|
}
|
||
|
}
|
||
|
#endregion // PropertyTabCollection Class
|
||
|
|
||
|
#region Private Helper Methods
|
||
|
|
||
|
private GridItem FindFirstPropertyItem (GridItem root)
|
||
|
{
|
||
|
if (root.GridItemType == GridItemType.Property)
|
||
|
return root;
|
||
|
|
||
|
foreach (GridItem item in root.GridItems) {
|
||
|
GridItem subitem = FindFirstPropertyItem (item);
|
||
|
if (subitem != null)
|
||
|
return subitem;
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
private GridEntry GetDefaultPropertyItem (GridEntry rootItem, PropertyTab propertyTab)
|
||
|
{
|
||
|
if (rootItem == null || rootItem.GridItems.Count == 0 || propertyTab == null)
|
||
|
return null;
|
||
|
object[] propertyOwners = rootItem.Values;
|
||
|
if (propertyOwners == null || propertyOwners.Length == 0 || propertyOwners[0] == null)
|
||
|
return null;
|
||
|
|
||
|
GridItem defaultSelected = null;
|
||
|
if (propertyOwners.Length > 1)
|
||
|
defaultSelected = rootItem.GridItems[0];
|
||
|
else {
|
||
|
PropertyDescriptor defaultProperty = propertyTab.GetDefaultProperty (propertyOwners[0]);
|
||
|
if (defaultProperty != null)
|
||
|
defaultSelected = FindItem (defaultProperty.Name, rootItem);
|
||
|
if (defaultSelected == null)
|
||
|
defaultSelected = FindFirstPropertyItem (rootItem);
|
||
|
}
|
||
|
|
||
|
return defaultSelected as GridEntry;
|
||
|
}
|
||
|
|
||
|
private GridEntry FindItem (string name, GridEntry rootItem)
|
||
|
{
|
||
|
if (rootItem == null || name == null)
|
||
|
return null;
|
||
|
|
||
|
if (property_sort == PropertySort.Alphabetical || property_sort == PropertySort.NoSort) {
|
||
|
foreach (GridItem item in rootItem.GridItems) {
|
||
|
if (item.Label == name) {
|
||
|
return (GridEntry)item;
|
||
|
}
|
||
|
}
|
||
|
} else if (property_sort == PropertySort.Categorized ||
|
||
|
property_sort == PropertySort.CategorizedAlphabetical) {
|
||
|
foreach (GridItem categoryItem in rootItem.GridItems) {
|
||
|
foreach (GridItem item in categoryItem.GridItems) {
|
||
|
if (item.Label == name) {
|
||
|
return (GridEntry)item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
private void OnResetPropertyClick (object sender, EventArgs e)
|
||
|
{
|
||
|
ResetSelectedProperty();
|
||
|
}
|
||
|
|
||
|
private void OnDescriptionClick (object sender, EventArgs e)
|
||
|
{
|
||
|
this.HelpVisible = !this.HelpVisible;
|
||
|
description_menuitem.Checked = this.HelpVisible;
|
||
|
}
|
||
|
|
||
|
private void PopulateGrid (object[] objects)
|
||
|
{
|
||
|
if (objects.Length > 0) {
|
||
|
root_grid_item = new RootGridEntry (this, objects);
|
||
|
root_grid_item.Expanded = true;
|
||
|
UpdateSortLayout (root_grid_item);
|
||
|
} else {
|
||
|
root_grid_item = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void UpdateSortLayout (GridEntry rootItem)
|
||
|
{
|
||
|
if (rootItem == null)
|
||
|
return;
|
||
|
|
||
|
GridItemCollection reordered = new GridItemCollection ();
|
||
|
|
||
|
if (property_sort == PropertySort.Alphabetical || property_sort == PropertySort.NoSort) {
|
||
|
alphabetic_toolbarbutton.Pushed = true;
|
||
|
categorized_toolbarbutton.Pushed = false;
|
||
|
foreach (GridItem item in rootItem.GridItems) {
|
||
|
if (item.GridItemType == GridItemType.Category) {
|
||
|
foreach (GridItem categoryChild in item.GridItems) {
|
||
|
reordered.Add (categoryChild);
|
||
|
((GridEntry)categoryChild).SetParent (rootItem);
|
||
|
}
|
||
|
} else {
|
||
|
reordered.Add (item);
|
||
|
}
|
||
|
}
|
||
|
} else if (property_sort == PropertySort.Categorized ||
|
||
|
property_sort == PropertySort.CategorizedAlphabetical) {
|
||
|
alphabetic_toolbarbutton.Pushed = false;
|
||
|
categorized_toolbarbutton.Pushed = true;
|
||
|
GridItemCollection categories = new GridItemCollection ();
|
||
|
|
||
|
foreach (GridItem item in rootItem.GridItems) {
|
||
|
if (item.GridItemType == GridItemType.Category) {
|
||
|
categories.Add (item);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
string categoryName = item.PropertyDescriptor.Category;
|
||
|
if (categoryName == null)
|
||
|
categoryName = UNCATEGORIZED_CATEGORY_LABEL;
|
||
|
GridItem category_item = rootItem.GridItems [categoryName];
|
||
|
if (category_item == null)
|
||
|
category_item = categories [categoryName];
|
||
|
|
||
|
if (category_item == null) {
|
||
|
// Create category grid items if they already don't
|
||
|
category_item = new CategoryGridEntry (this, categoryName, rootItem);
|
||
|
category_item.Expanded = true;
|
||
|
categories.Add (category_item);
|
||
|
}
|
||
|
|
||
|
category_item.GridItems.Add (item);
|
||
|
((GridEntry)item).SetParent (category_item);
|
||
|
}
|
||
|
|
||
|
reordered.AddRange (categories);
|
||
|
}
|
||
|
|
||
|
rootItem.GridItems.Clear ();
|
||
|
rootItem.GridItems.AddRange (reordered);
|
||
|
}
|
||
|
|
||
|
private void help_panel_Paint(object sender, PaintEventArgs e) {
|
||
|
e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(help_panel.BackColor), help_panel.ClientRectangle );
|
||
|
e.Graphics.DrawRectangle(SystemPens.ControlDark, 0,0,help_panel.Width-1,help_panel.Height-1 );
|
||
|
}
|
||
|
|
||
|
#endregion // Private Helper Methods
|
||
|
|
||
|
#region Internal helper classes
|
||
|
// as we can not change the color for BorderStyle.FixedSingle and we need the correct
|
||
|
// ClientRectangle so that the ScrollBar doesn't draw over the border we need this class
|
||
|
internal class BorderHelperControl : Control {
|
||
|
|
||
|
public BorderHelperControl ()
|
||
|
{
|
||
|
BackColor = ThemeEngine.Current.ColorWindow;
|
||
|
}
|
||
|
|
||
|
protected override void OnPaint (PaintEventArgs e)
|
||
|
{
|
||
|
e.Graphics.DrawRectangle (SystemPens.ControlDark, 0 , 0 , Width - 1, Height - 1);
|
||
|
base.OnPaint (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnSizeChanged (EventArgs e)
|
||
|
{
|
||
|
if (Controls.Count == 1) {
|
||
|
Control control = Controls [0];
|
||
|
|
||
|
if (control.Location.X != 1 || control.Location.Y != 1)
|
||
|
control.Location = new Point (1, 1);
|
||
|
|
||
|
control.Width = ClientRectangle.Width - 2;
|
||
|
control.Height = ClientRectangle.Height - 2;
|
||
|
}
|
||
|
base.OnSizeChanged (e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private class PropertyToolBarSeparator : ToolStripSeparator
|
||
|
{
|
||
|
public PropertyToolBarSeparator ()
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private class PropertyToolBarButton : ToolStripButton
|
||
|
{
|
||
|
private PropertyTab property_tab;
|
||
|
|
||
|
public PropertyToolBarButton ()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public PropertyToolBarButton (PropertyTab propertyTab)
|
||
|
{
|
||
|
if (propertyTab == null)
|
||
|
throw new ArgumentNullException ("propertyTab");
|
||
|
property_tab = propertyTab;
|
||
|
}
|
||
|
|
||
|
public PropertyTab PropertyTab {
|
||
|
get { return property_tab; }
|
||
|
}
|
||
|
|
||
|
public bool Pushed {
|
||
|
get { return base.Checked; }
|
||
|
set { base.Checked = value; }
|
||
|
}
|
||
|
|
||
|
public ToolBarButtonStyle Style {
|
||
|
get { return ToolBarButtonStyle.PushButton; }
|
||
|
set { }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// needed! this little helper makes it possible to draw a different toolbar border
|
||
|
// and toolbar backcolor in ThemeWin32Classic
|
||
|
internal class PropertyToolBar : ToolStrip
|
||
|
{
|
||
|
ToolBarAppearance appearance;
|
||
|
|
||
|
public PropertyToolBar ()
|
||
|
{
|
||
|
SetStyle (ControlStyles.ResizeRedraw, true);
|
||
|
GripStyle = ToolStripGripStyle.Hidden;
|
||
|
appearance = ToolBarAppearance.Normal;
|
||
|
}
|
||
|
|
||
|
public bool ShowToolTips {
|
||
|
get { return base.ShowItemToolTips; }
|
||
|
set { base.ShowItemToolTips = value; }
|
||
|
}
|
||
|
|
||
|
public ToolBarAppearance Appearance {
|
||
|
get { return appearance; }
|
||
|
set {
|
||
|
if (value == Appearance)
|
||
|
return;
|
||
|
|
||
|
switch (value) {
|
||
|
case ToolBarAppearance.Flat:
|
||
|
Renderer = new ToolStripSystemRenderer ();
|
||
|
appearance = ToolBarAppearance.Flat;
|
||
|
break;
|
||
|
case ToolBarAppearance.Normal:
|
||
|
ProfessionalColorTable table = new ProfessionalColorTable ();
|
||
|
table.UseSystemColors = true;
|
||
|
Renderer = new ToolStripProfessionalRenderer (table);
|
||
|
appearance = ToolBarAppearance.Normal;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
[MonoInternalNote ("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")]
|
||
|
private class SelectedObjectConverter : TypeConverter
|
||
|
{
|
||
|
}
|
||
|
#endregion
|
||
|
}
|
||
|
}
|