#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using DevComponents.AdvTree;
using System.ComponentModel;
using System.Reflection;
using DevComponents.DotNetBar.Controls;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Drawing.Imaging;
using System.Collections;
using System.Threading;
namespace DevComponents.DotNetBar
{
    /// 
    /// Represents a property node in AdvPropertyGrid.
    /// 
    public class PropertyNode : Node, ITypeDescriptorContext, IWindowsFormsEditorService
    {
        #region Private Variables
        private const string ID_UITypeEditorImage = "UITypeEditorImage";
        #endregion
        #region Constructors
        private PropertyDescriptor _Property = null;
        /// 
        /// Initializes a new instance of the PropertyNode class.
        /// 
        /// 
        public PropertyNode(PropertyDescriptor property)
        {
            _Property = property;
            this.CellNavigationEnabled = false;
            PasswordPropertyTextAttribute passwordAttribute = _Property.Attributes[typeof(PasswordPropertyTextAttribute)] as PasswordPropertyTextAttribute;
            if (passwordAttribute != null && passwordAttribute.Password)
                IsPassword = true;
        }
        #endregion
        #region Internal Implementation
        public virtual void UpdateDisplayedValue()
        {
            UpdateDisplayedValue(true);
        }
        public virtual void UpdateDisplayedValue(bool refreshSubProperties)
        {
            if (_IsDisposed || _IsDisposing) return;
            object propertyValue = PropertyValue;
            UpdateDisplayedValue(propertyValue, refreshSubProperties);
        }
        protected virtual void UpdateDisplayedValue(object propertyValue)
        {
            UpdateDisplayedValue(propertyValue, true);
        }
        protected virtual void UpdateDisplayedValue(object propertyValue, bool refreshSubProperties)
        {
            if (_IsDisposed || _IsDisposing) return;
            // Value cell
            Cell cell = this.EditCell;
            cell.Text = GetPropertyTextValue(propertyValue);
            if (GetIsDefaultValue(propertyValue))
            {
                cell.StyleNormal = EditCellStyle;
            }
            else
            {
                cell.StyleNormal = ValueChangedStyle;
            }
            RevertEditorValue();
            if (IsTypeEditorPaintValueSupported)
            {
                UITypeEditor typeEditor = GetTypeEditor();
                if (typeEditor != null && typeEditor.GetPaintValueSupported(this))
                {
                    Rectangle r = new Rectangle(0, 0, 20, 13);
                    Bitmap image = new Bitmap(r.Width, r.Height, PixelFormat.Format32bppArgb);
                    image.Tag = ID_UITypeEditorImage;
                    using (Graphics g = Graphics.FromImage(image))
                    {
                        bool error = false;
                        try
                        {
                            typeEditor.PaintValue(new PaintValueEventArgs(this, propertyValue, g, r));
                            //typeEditor.PaintValue(propertyValue, g, r);
                        }
                        catch
                        {
                            error = true;
                        }
                        if (error)
                            DisplayHelp.FillRectangle(g, r, Color.White);
                        DisplayHelp.DrawRectangle(g, SwatchBorderColor, r);
                    }
                    cell.Images.Image = image;
                }
                else
                {
                    if (cell.Images.Image != null && cell.Images.Image.Tag is string && (string)cell.Images.Image.Tag == ID_UITypeEditorImage)
                    {
                        Image image = cell.Images.Image;
                        cell.Images.Image = null;
                        image.Dispose();
                    }
                }
            }
            if (refreshSubProperties)
            {
                UpdateChildProperties();
                //if (this.HasChildNodes && this.Expanded)
                //    LoadChildProperties();
            }
        }
        private Color _SwatchBorderColor = Color.Black;
        private Color SwatchBorderColor
        {
            get
            {
                return _SwatchBorderColor;
            }
        }
        protected virtual bool IsTypeEditorPaintValueSupported
        {
            get
            {
                return true;
            }
        }
        private string GetPropertyTextValue()
        {
            return GetPropertyTextValue(this.PropertyValue);
        }
        protected string GetPropertyTextValue(object propertyValue)
        {
            if (_PropertySettings != null && _PropertySettings.HasConvertPropertyValueToStringHandler)
            {
                ConvertValueEventArgs e = new ConvertValueEventArgs(null, propertyValue, GetPropertyName(), GetTargetComponent(), PropertyDescriptor);
                _PropertySettings.InvokeConvertPropertyValueToString(e);
                if (e.IsConverted && e.StringValue != null)
                    return e.StringValue;
            }
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null && grid.HasConvertPropertyValueToStringHandler)
            {
                ConvertValueEventArgs e = new ConvertValueEventArgs(null, propertyValue, GetPropertyName(), GetTargetComponent(), PropertyDescriptor);
                grid.InvokeConvertPropertyValueToString(e);
                if (e.IsConverted && e.StringValue != null)
                    return e.StringValue;
            }
            string textValue = null;
            TypeConverter typeConverter = this.TypeConverter;
            try
            {
                textValue = typeConverter.ConvertToString(this, propertyValue);
            }
            catch (Exception)
            {
            }
            if (textValue == null)
            {
                textValue = string.Empty;
            }
            if (IsPassword)
            {
                textValue = StringHelper.Repeat(AdvPropertyGrid.PasswordChar, textValue.Length);
            }
            return textValue;
        }
        private TypeConverter _TypeConverter = null;
        internal virtual TypeConverter TypeConverter
        {
            get
            {
                if (_PropertySettings != null && _PropertySettings.TypeConverter != null)
                    return _PropertySettings.TypeConverter;
                if (_TypeConverter == null)
                {
                    _TypeConverter = GetPropertyDescriptor().Converter;
                }
                return _TypeConverter;
            }
        }
        public virtual Type PropertyType
        {
            get
            {
                object propertyValue = this.PropertyValue;
                if (propertyValue != null)
                {
                    return propertyValue.GetType();
                }
                else
                    return _Property.PropertyType;
                return null;
            }
        }
        public virtual object PropertyValue
        {
            get
            {
                try
                {
                    object propertyValue = this.GetPropertyValue(this.GetTargetComponent());
                    return propertyValue;
                }
                catch (Exception exception)
                {
                    return exception;
                }
            }
            set
            {
                ApplyValue(value, null);
            }
        }
        protected virtual bool GetIsDefaultValue()
        {
            return GetIsDefaultValue(PropertyValue);
        }
        private bool GetIsDefaultValue(object propertyValue)
        {
            DefaultValueAttribute defaultValueAttribute = GetPropertyDescriptor().Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
            if (defaultValueAttribute != null)
            {
                if (defaultValueAttribute.Value != null)
                    return (defaultValueAttribute.Value.Equals(propertyValue));
                return defaultValueAttribute.Value == propertyValue;
            }
            if (propertyValue != null)
            {
                string strfunct = "ShouldSerialize" + GetPropertyName();
                PropertyDescriptor propDesc = GetPropertyDescriptor();
                if (propDesc != null && propDesc.ComponentType != null && propDesc.ComponentType.GetMethod(strfunct, BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) != null)
                {
                    MethodInfo mi = propDesc.ComponentType.GetMethod(strfunct, BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                    object target = GetTargetComponent();
                    if (mi.DeclaringType.IsInstanceOfType(target)) // If method is injected by designer code we need to detect that to avoid Invalid Target Exception from RunTimeMethodInfo.CheckConsistency
                    {
                        object result = mi.Invoke(GetTargetComponent(), null);
                        if (result is bool && ((bool)result))
                            return false;
                    }
                }
            }
            return true;
        }
        protected virtual object GetTargetComponent()
        {
            if (_TargetComponent != null) return _TargetComponent;
            Node node = this.Parent as Node;
            while (node != null)
            {
                if (node is PropertyNode)
                    return ((PropertyNode)node).GetTargetComponent();
                node = node.Parent as Node;
            }
            return _TargetComponent;
        }
        private object _TargetComponent;
        internal object TargetComponent
        {
            get { return _TargetComponent; }
            set
            {
                object oldValue = _TargetComponent;
                _TargetComponent = value;
                OnTargetComponentChanged(oldValue, value);
            }
        }
        private bool _PropertyChangedEventHandled = false;
        protected virtual void OnTargetComponentChanged(object oldValue, object newValue)
        {
            string eventName = GetPropertyName() + "Changed";
            if (oldValue != null && _PropertyChangedEventHandled)
            {
                try
                {
                    if (oldValue is ICustomTypeDescriptor)
                    {
                        EventDescriptor item = GetEventDescriptor(oldValue, eventName);
                        if (item != null)
                            item.RemoveEventHandler(oldValue, this.PropertyValueChangedEventHandler);
                    }
                    else
                    {
                        EventInfo info = oldValue.GetType().GetEvent(eventName);
                        if (info != null)
                            info.RemoveEventHandler(oldValue, this.PropertyValueChangedEventHandler);
                    }
                }
                finally
                {
                    _PropertyChangedEventHandled = false;
                }
            }
            if (newValue != null && GetPropertyDescriptor() != null)
            {
                // Check whether object has PropertyNameChanged event handler...
                if (newValue is ICustomTypeDescriptor)
                {
                    EventDescriptor item = GetEventDescriptor(newValue, eventName);
                    if (item != null)
                    {
                        try
                        {
                            item.AddEventHandler(newValue, PropertyValueChangedEventHandler);
                            _PropertyChangedEventHandled = true;
                        }
                        catch
                        {
                            _PropertyChangedEventHandled = false;
                        }
                    }
                }
                else
                {
                    EventInfo info = newValue.GetType().GetEvent(eventName);
                    if (info != null && info.EventHandlerType == typeof(EventHandler))
                    {
                        try
                        {
                            info.AddEventHandler(newValue, PropertyValueChangedEventHandler);
                            _PropertyChangedEventHandled = true;
                        }
                        catch
                        {
                            _PropertyChangedEventHandled = false;
                        }
                    }
                }
            }
        }
        private EventDescriptor GetEventDescriptor(object value, string eventName)
        {
            EventDescriptorCollection col = ((ICustomTypeDescriptor)value).GetEvents();
            foreach (EventDescriptor item in col)
            {
                if (item.Name == eventName)
                {
                    if (item.EventType == typeof(EventHandler))
                    {
                        return item;
                    }
                    break;
                }
            }
            return null;
        }
        private void PropertyValueChanged(object sender, EventArgs e)
        {
            UpdateDisplayedValue();
        }
        private EventHandler _PropertyValueChangedEventHandler = null;
        private EventHandler PropertyValueChangedEventHandler
        {
            get
            {
                if (_PropertyValueChangedEventHandler == null)
                    _PropertyValueChangedEventHandler = new EventHandler(PropertyValueChanged);
                return _PropertyValueChangedEventHandler;
            }
        }
        protected virtual object GetPropertyValue(object target)
        {
            PropertyDescriptor propertyDescriptor = GetPropertyDescriptor();
            if (propertyDescriptor == null)
            {
                return null;
            }
            if (_IsMultiObject)
            {
                object[] targets = (object[])target;
                object returnValue = GetPropertyValueCore(targets[0], propertyDescriptor);
                TypeConverter converter = this.TypeConverter;
                for (int i = 1; i < targets.Length; i++)
                {
                    object value = null;
                    if (propertyDescriptor.ComponentType.IsAssignableFrom(targets[i].GetType()))
                        value = GetPropertyValueCore(targets[i], propertyDescriptor);
                    else
                    {
                        //PropertyDescriptor desc2 = PropertyParser.GetProperty(propertyDescriptor.Name, targets[i], converter.GetPropertiesSupported(this) ? converter : null);
                        PropertyDescriptor desc2 = PropertyParser.GetProperty(propertyDescriptor.Name, targets[i], null);
                        value = GetPropertyValueCore(targets[i], desc2);
                    }
                    if (returnValue != null && !returnValue.Equals(value) || returnValue == null && value != null)
                    {
                        returnValue = null;
                        break;
                    }
                }
                return returnValue;
            }
            else
            {
                return GetPropertyValueCore(target, propertyDescriptor);
            }
        }
        protected virtual object GetPropertyValueCore(object target, PropertyDescriptor propertyDescriptor)
        {
            object propertyValue;
            if (target is ICustomTypeDescriptor)
            {
                target = ((ICustomTypeDescriptor)target).GetPropertyOwner(propertyDescriptor);
            }
            try
            {
                propertyValue = propertyDescriptor.GetValue(target);
            }
            catch
            {
                throw;
            }
            return propertyValue;
        }
        public PropertyDescriptor PropertyDescriptor
        {
            get
            {
                return _Property;
            }
            internal set
            {
                _Property = value;
                UpdateValueInlineEditor();
            }
        }
        protected override void OnParentChanged()
        {
            UpdateValueInlineEditor();
            base.OnParentChanged();
        }
        private bool IsEditorReadOnly
        {
            get
            {
                PropertyDescriptor propDesc = PropertyDescriptor;
                if (propDesc != null) return propDesc.IsReadOnly;
                return false;
            }
        }
        /// 
        /// Releases the inline editor used by the node.
        /// 
        public virtual void ReleaseInlineEditor()
        {
            UpdateValueInlineEditor();
        }
        private bool _IsUsingInlineEditor = false;
        private void UpdateValueInlineEditor()
        {
            if (_IsUsingInlineEditor)
            {
                Cell editCell = this.EditCell;
                Control editor = editCell.HostedControl;
                if (editor != null)
                {
                    editCell.HostedControl = null;
                    if (editor is IPropertyValueEditor)
                        ((IPropertyValueEditor)editor).EditValueChanged -= ValueEditorEditValueChanged;
                    editor.Dispose();
                }
                else if (editCell.HostedItem != null)
                {
                    BaseItem item = editCell.HostedItem;
                    editCell.HostedItem = null;
                    if (item is IPropertyValueEditor)
                        ((IPropertyValueEditor)item).EditValueChanged -= ValueEditorEditValueChanged;
                    item.Dispose();
                }
            }
            _IsUsingInlineEditor = false;
            if (_Property == null || IsDisposing) return;
            PropertyValueEditor valueEditor;
            if (_PropertySettings != null && _PropertySettings.ValueEditor != null)
                valueEditor = _PropertySettings.ValueEditor;
            else
                valueEditor = _Property.Attributes[typeof(PropertyValueEditor)] as PropertyValueEditor;
            if (valueEditor != null)
            {
                IPropertyValueEditor editorCustom = valueEditor.CreateEditor(_Property, _TargetComponent);
                editorCustom.EditValueChanged += ValueEditorEditValueChanged;
                _Editor = editorCustom;
                if (editorCustom is Control)
                {
                    this.EditCell.HostedControl = (Control)_Editor;
                    if (this.IsReadOnly || this.IsEditorReadOnly) this.EditCell.HostedControl.Enabled = false;
                }
                else if (editorCustom is BaseItem)
                {
                    this.EditCell.HostedItem = (BaseItem)_Editor;
                    if (this.IsReadOnly || this.IsEditorReadOnly) this.EditCell.Enabled = false;
                }
                else
                    throw new ArgumentException("PropertyValueEditor must inherit from Control or BaseItem.");
                _IsUsingInlineEditor = true;
            }
        }
        private ElementStyle _ValueChangedStyle = null;
        public ElementStyle ValueChangedStyle
        {
            get
            {
                if (_ValueChangedStyle == null)
                {
                    IPropertyElementStyleProvider styleProvider = StyleProvider;
                    if (styleProvider != null) return styleProvider.ValueChangedStyle;
                }
                return _ValueChangedStyle;
            }
            set
            {
                _ValueChangedStyle = value;
            }
        }
        private ElementStyle _EditCellStyle = null;
        public ElementStyle EditCellStyle
        {
            get
            {
                if (_EditCellStyle == null)
                {
                    IPropertyElementStyleProvider styleProvider = StyleProvider;
                    if (styleProvider != null) return styleProvider.DefaultEditCellStyle;
                }
                return _EditCellStyle;
            }
            set
            {
                if (_EditCellStyle != value)
                {
                    _EditCellStyle = value;
                    UpdateDisplayedValue();
                }
            }
        }
        object _Editor = null;
        protected override void OnSelected(eTreeAction action)
        {
            if (_IsDisposed || _IsDisposing) return;
            UpdateDisplayedValue();
            AdvTree.AdvTree tree = this.TreeControl;
            bool focusEditor = false;
            Point pos = Point.Empty;
            if (tree != null)
            {
                pos = tree.PointToClient(Control.MousePosition);
                if (this.EditCell.Bounds.Contains(pos))
                    focusEditor = true;
            }
            if (action == eTreeAction.Keyboard && WinApi.HIWORD(WinApi.GetKeyState(9)) != 0)
                focusEditor = true;
            if (this.Enabled && (!this.IsReadOnly && CanEditPropertyContent()))
            {
                EnterEditorMode(action, focusEditor);
                if (focusEditor && !pos.IsEmpty && _Editor is TextBoxDropDown)
                {
                    ((TextBoxDropDown)_Editor).TextBox.SelectAll();
                }
            }
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null)
            {
                string description = GetDescriptionAttributeValue();
                if (!string.IsNullOrEmpty(description))
                {
                    bool replaceNewLineCharacters = false;
                    if (!TextMarkup.MarkupParser.IsMarkup(ref description))
                        replaceNewLineCharacters = true;
                    description = description.Replace("<", "<"); description = description.Replace(">", ">");
                    description = "" + this.Text + "
" + description;
                    if (replaceNewLineCharacters)
                        description = description.Replace("\n", "
");
                }
                grid.HelpPanel.Text = description;
            }
            base.OnSelected(action);
        }
        private string _Description = null;
        private string GetDescriptionAttributeValue()
        {
            if (_PropertySettings != null && _PropertySettings.Description != null)
                return _PropertySettings.Description;
            if (_Description == null)
            {
                _Description = _Property.Description;
                //DescriptionAttribute att = _Property.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute;
                //if (att != null)
                //    _Description = att.Description;
                //else
                //    _Description = "";
            }
            return _Description;
        }
        internal TextBoxDropDown GetEditor()
        {
            return _Editor as TextBoxDropDown;
        }
        private bool IsUsingPropertyEditor()
        {
            if (_Property != null && !_Property.PropertyType.IsPrimitive && !_Property.PropertyType.IsEnum && !(_Property.PropertyType == typeof(string)))
            {
                UITypeEditor editor = GetTypeEditor();
                if (editor != null) //  && (editor.GetEditStyle(this) == UITypeEditorEditStyle.Modal || editor.GetEditStyle(this) == UITypeEditorEditStyle.None)
                    return true;
            }
            return false;
        }
        private bool CanEditPropertyContent()
        {
            if (_Property != null && !_Property.PropertyType.IsPrimitive && !_Property.PropertyType.IsEnum && !(_Property.PropertyType == typeof(string)))
            {
                UITypeEditor editor = GetTypeEditor();
                if (editor != null) //  && (editor.GetEditStyle(this) == UITypeEditorEditStyle.Modal || editor.GetEditStyle(this) == UITypeEditorEditStyle.None)
                    return true;
                else
                {
                    if (this.TypeConverter != null && this.TypeConverter.CanConvertFrom(typeof(string)))
                        return true;
                    return false;
                }
            }
            return true;
        }
        private bool _IsReadOnly = false;
        /// 
        /// Gets or sets whether property text box is read only. Default value is false.
        /// 
        public bool IsReadOnly
        {
            get { return _IsReadOnly; }
            set
            {
                if (_IsReadOnly == value) return;
                _IsReadOnly = value;
                if (_IsReadOnly)
                    this.Style = GetReadOnlyStyle();
                else
                    this.Style = GetDefaultStyle();
                OnIsReadOnlyChanged();
            }
        }
        protected virtual void OnIsReadOnlyChanged()
        {
            Cell editCell = this.EditCell;
            if (editCell == null) return;
            if (editCell.HostedControl is IPropertyValueEditor)
                editCell.HostedControl.Enabled = !_IsReadOnly;
            if (editCell.HostedItem is IPropertyValueEditor)
                editCell.HostedItem.Enabled = !_IsReadOnly;
        }
        private ElementStyle GetReadOnlyStyle()
        {
            if (_PropertySettings != null && _PropertySettings.ReadOnlyStyle != null)
                return _PropertySettings.ReadOnlyStyle;
            IPropertyElementStyleProvider styleProvider = this.StyleProvider;
            if (styleProvider != null)
            {
                return styleProvider.ReadOnlyStyle;
            }
            return null;
        }
        public IPropertyElementStyleProvider StyleProvider
        {
            get
            {
                return AdvPropertyGrid as IPropertyElementStyleProvider;
            }
        }
        private ElementStyle GetDefaultStyle()
        {
            if (_PropertySettings != null && _PropertySettings.Style != null)
                return _PropertySettings.Style;
            return null;
        }
        protected virtual Cell EditCell
        {
            get
            {
                return this.Cells[1];
            }
        }
        protected override bool CanKeyboardNavigate(KeyEventArgs e)
        {
            return !IsEditing || IsEditing && (_Editor is TextBoxDropDown && !((TextBoxDropDown)_Editor).TextBox.Focused ||
                _Editor is IPropertyValueEditor && ((IPropertyValueEditor)_Editor).IsEditorFocused);
        }
        /// 
        /// Gets whether node is in editing mode.
        /// 
        public bool IsEditing
        {
            get
            {
                return _IsEditing;
            }
            internal set
            {
                if (_IsEditing != value)
                {
                    _IsEditing = value;
                    AdvPropertyGrid grid = AdvPropertyGrid;
                    if (grid != null)
                        grid.OnPropertyIsEditingChanged(this);
                }
            }
        }
        private bool _IsEditing = false;
        /// 
        /// Places the node into the editing mode if possible, raises the exception if node is read-only.
        /// 
        /// Action that caused the edit mode.
        /// Indicates whether to focus the editor.
        public virtual void EnterEditorMode(eTreeAction action, bool focusEditor)
        {
            if (IsEditing)
                throw new InvalidOperationException("Node is already in edit mode.");
            if (!Enabled)
                throw new InvalidOperationException("Node is disabled. Cannot enter edit mode.");
            if (_IsUsingInlineEditor)
            {
                if (_Editor is IPropertyValueEditor)
                    ((IPropertyValueEditor)_Editor).EditValue = PropertyValue;
                IsEditing = true;
                if (focusEditor)
                {
                    if (_Editor is IPropertyValueEditor)
                        ((IPropertyValueEditor)_Editor).FocusEditor();
                }
                EditValueChanged = false;
                return;
            }
            if (_Editor == null)
            {
                _Editor = CreateNodeEditor();
                TextBoxDropDown editor = _Editor as TextBoxDropDown;
                if (editor != null)
                {
                    if (IsPassword)
                    {
                        editor.PasswordChar = AdvPropertyGrid.PasswordChar;
                        editor.Text = GetPropertyTextValue();
                    }
                    else
                    {
                        editor.PasswordChar = '\0';
                        editor.Text = this.EditCell.Text;
                    }
                }
                else if (_Editor is IPropertyValueEditor)
                {
                    ((IPropertyValueEditor)_Editor).EditValue = PropertyValue;
                    if (!IsReadOnly)
                        ((Control)_Editor).Enabled = false;
                }
                ElementStyle valueChangedStyle = this.ValueChangedStyle;
                if (this.EditCell.StyleNormal == valueChangedStyle && valueChangedStyle.Font != null)
                {
                    if (editor != null)
                        editor.TextBox.Font = valueChangedStyle.Font;
                    else if (_Editor is IPropertyValueEditor)
                        ((IPropertyValueEditor)_Editor).EditorFont = valueChangedStyle.Font;
                }
                this.EditCell.HostedControl = (Control)_Editor;
                IsEditing = true;
                if (focusEditor)
                {
                    if (editor != null)
                        editor.Focus();
                    else if (_Editor is IPropertyValueEditor)
                        ((IPropertyValueEditor)_Editor).FocusEditor();
                }
                EditValueChanged = false;
            }
        }
        protected virtual Control CreateNodeEditor()
        {
            bool isReadOnly = GetEffectiveReadOnly();
            //PropertyValueEditor valueEditor = _Property.Attributes[typeof(PropertyValueEditor)] as PropertyValueEditor;
            //if (valueEditor != null)
            //{
            //    IPropertyValueEditor editorCustom = valueEditor.CreateEditor(_Property, _TargetComponent);
            //    editorCustom.EditValueChanged += ValueEditorEditValueChanged;
            //    return (Control)editorCustom;
            //}
            TextBoxDropDown editor = new TextBoxDropDown();
            if (BarUtilities.UseTextRenderer)
                editor.BackgroundStyle.MarginLeft = 3;
            AdvPropertyGrid grid = this.AdvPropertyGrid;
            if (grid != null) editor.Font = grid.Font;
            editor.Size = new Size(32, editor.PreferredHeight);
            editor.Visible = true;
            editor.TextBox.KeyDown += new KeyEventHandler(EditorKeyDown);
            editor.TextBox.TextChanged += new EventHandler(EditorTextChanged);
            editor.TextBox.ReadOnly = isReadOnly;
            editor.TextBox.PreventEnterBeep = true;
            UITypeEditor typeEditor = GetTypeEditor();
            UITypeEditorEditStyle editStyle = UITypeEditorEditStyle.None;
            if (typeEditor != null)
            {
                editStyle = typeEditor.GetEditStyle(this);
                if (editStyle == UITypeEditorEditStyle.Modal)
                {
                    editor.ButtonCustom.Visible = true;
                    editor.ButtonCustomClick += new EventHandler(EditorButtonCustomClick);
                }
                else if (editStyle == UITypeEditorEditStyle.DropDown)
                {
                    editor.ButtonDropDown.Visible = true;
                    editor.ButtonDropDownClick += new CancelEventHandler(EditorButtonDropDownClick);
                }
                if (!IsReadOnly)
                {
                    PropertyDescriptor propertyDescriptor = GetPropertyDescriptor();
                    if (propertyDescriptor != null && !propertyDescriptor.PropertyType.IsAssignableFrom(typeof(string)) &&
                        propertyDescriptor.Converter != null && !propertyDescriptor.Converter.CanConvertFrom(typeof(string)))
                        editor.TextBox.ReadOnly = true;
                }
            }
            if (typeEditor == null || editStyle == UITypeEditorEditStyle.None)
            {
                if (!isReadOnly)
                {
                    SetupEditorAutoCompleteList(editor);
                    if (!SetupEditorPopup(editor))
                        editor.ButtonDropDown.Visible = false;
                    else
                    {
                        editor.ButtonDropDown.Visible = true;
                    }
                }
            }
            if (AfterEditorCreated != null)
                AfterEditorCreated(this, editor);
            return editor;
        }
        /// 
        /// Defines delegate that is called after property editor is created.
        /// 
        /// PropertyNode sender.
        /// Reference to editor.
        public delegate void AfterEditorCreatedDelegate(object sender, object editor);
        /// 
        /// Called after property editor is created.
        /// 
        public AfterEditorCreatedDelegate AfterEditorCreated;
        void ValueEditorEditValueChanged(object sender, EventArgs e)
        {
            EditValueChanged = true;
            if (IsEditing)
                ApplyEdit();
        }
        private bool ProcessEditorDropDownClick()
        {
            UITypeEditor typeEditor = GetTypeEditor();
            if (typeEditor != null && typeEditor.GetEditStyle(this) == UITypeEditorEditStyle.DropDown)
            {
                object value = typeEditor.EditValue(this, this, this.PropertyValue);
                ApplyValue(value, null);
                return true;
            }
            return false;
        }
        private void EditorButtonDropDownClick(object sender, CancelEventArgs e)
        {
            ProcessEditorDropDownClick();
            e.Cancel = true;
        }
        private bool GetEffectiveReadOnly()
        {
            return this.IsReadOnly;
        }
        private UITypeEditor GetTypeEditor()
        {
            PropertyDescriptor propertyDescriptor = GetPropertyDescriptor();
            if (_PropertySettings != null && _PropertySettings.UITypeEditor != null)
            {
                return _PropertySettings.UITypeEditor;
            }
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null && grid.HasProvideUITypeEditorHandler)
            {
                ProvideUITypeEditorEventArgs args = new ProvideUITypeEditorEventArgs(GetPropertyName(), propertyDescriptor);
                grid.InvokeProvideUITypeEditor(args);
                if (args.EditorSpecified) return args.UITypeEditor;
            }
            object value = PropertyValue;
            if (value is ICustomTypeDescriptor)
            {
                ICustomTypeDescriptor descriptor = (ICustomTypeDescriptor)value;
                UITypeEditor editor = (UITypeEditor)descriptor.GetEditor(typeof(UITypeEditor));
                if (editor != null)
                    return editor;
            }
            return (UITypeEditor)propertyDescriptor.GetEditor(typeof(UITypeEditor));
        }
        internal string PropertyName
        {
            get
            {
                return GetPropertyName();
            }
        }
        protected virtual string GetPropertyName()
        {
            return GetPropertyDescriptor().Name;
        }
        protected virtual PropertyDescriptor GetPropertyDescriptor()
        {
            return _Property;
        }
        private void EditorButtonCustomClick(object sender, EventArgs e)
        {
            // Invoke this delayed and out of loop since MFC dialogs did not get focus when shown directly from this event handler.
            BarUtilities.InvokeDelayed(new MethodInvoker(delegate
            {
                UITypeEditor typeEditor = GetTypeEditor();
                if (typeEditor == null) return;
                object value = null;
                try
                {
                    value = typeEditor.EditValue(this, this, this.PropertyValue);
                }
                catch (Exception ex)
                {
                    MessageBoxEx.Show(ex.Message);
                    return;
                }
                ApplyValue(value, null);
            }));
        }
        protected virtual bool SetupEditorPopup(TextBoxDropDown editor)
        {
            if (this.PropertyType == null) return false;
            string[] items = GetPopupListContent();
            if (items == null || items.Length == 0) return false;
            TextBoxDropDown textBox = editor;
            ListBox list = new ListBox();
            list.SelectedIndexChanged += new EventHandler(PopupListSelectedIndexChanged);
            list.BorderStyle = BorderStyle.None;
            list.Items.AddRange(items);
            if (!string.IsNullOrEmpty(editor.Text))
                list.SelectedItem = editor.Text;
            textBox.DropDownControl = list;
            list.Size = GetPreferredListBoxSize(ref items);
            return true;
        }
        private void PopupListSelectedIndexChanged(object sender, EventArgs e)
        {
            ListBox list = (ListBox)sender;
            if (!list.Visible || list.SelectedItem == null) return;
            TextBoxDropDown editor = _Editor as TextBoxDropDown;
            editor.Text = (string)list.SelectedItem;
            editor.CloseDropDown();
            EditValueChanged = true;
            if (ApplyEdit())
            {
                AdvTree.AdvTree tree = this.TreeControl;
                if (tree != null) tree.Focus();
                this.SelectedCell = this.Cells[0];
            }
        }
        private Size _CachedPreferredListBoxSize = Size.Empty;
        private int _LastCacheListBoxItemCount = -1;
        protected virtual Size GetPreferredListBoxSize(ref string[] items)
        {
            if (items == null || items.Length == 0) return new Size(96, 32);
            AdvTree.AdvTree tree = this.TreeControl;
            if (tree == null) return new Size(96, 32);
            if (!_CachedPreferredListBoxSize.IsEmpty && _LastCacheListBoxItemCount == items.Length) return _CachedPreferredListBoxSize;
            Size totalSize = Size.Empty;
            using (Graphics g = tree.CreateGraphics())
            {
                Font font = tree.Font;
                for (int i = 0; i < items.Length; i++)
                {
                    Size itemSize = TextDrawing.MeasureString(g, items[i], font);
                    if (itemSize.Width == 0) itemSize.Width = this.EditCell.Bounds.Width - 8;
                    if (itemSize.Height == 0) itemSize.Height = font.Height;
                    totalSize.Width = Math.Max(itemSize.Width, totalSize.Width);
                    if (totalSize.Height < 320)
                        totalSize.Height += itemSize.Height;
                    else
                    {
                        if (totalSize.Width < 120) totalSize.Width = 128;
                        break;
                    }
                }
            }
            if (totalSize.Width < this.EditCell.Bounds.Width - 8)
                totalSize.Width = this.EditCell.Bounds.Width - 8;
            _CachedPreferredListBoxSize = totalSize;
            _LastCacheListBoxItemCount = items.Length;
            return totalSize;
        }
        protected virtual string[] GetPopupListContent()
        {
            if (_PropertySettings != null && _PropertySettings.HasProvidePropertyValueListHandler)
            {
                PropertyValueListEventArgs args = new PropertyValueListEventArgs(GetPropertyName(), GetTargetComponent(), PropertyDescriptor);
                _PropertySettings.InvokeProvidePropertyValueList(args);
                if (args.IsListValid)
                {
                    if (args.ValueList == null) return null;
                    return args.ValueList.ToArray();
                }
            }
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null && grid.HasProvidePropertyValueListHandler)
            {
                PropertyValueListEventArgs args = new PropertyValueListEventArgs(GetPropertyName(), GetTargetComponent(), PropertyDescriptor);
                grid.InvokeProvidePropertyValueList(args);
                if (args.IsListValid)
                {
                    if (args.ValueList == null) return null;
                    return args.ValueList.ToArray();
                }
            }
            TypeConverter converter = this.TypeConverter;
            if (converter != null && converter.GetStandardValuesSupported(this))
            {
                System.ComponentModel.TypeConverter.StandardValuesCollection stdValues = converter.GetStandardValues(this);
                if (stdValues != null && stdValues.Count > 0)
                {
                    string[] values = new string[stdValues.Count];
                    for (int i = 0; i < stdValues.Count; i++)
                    {
                        object item = stdValues[i];
                        values[i] = converter.ConvertToString(item);
                    }
                    return values;
                }
            }
            if (this.PropertyType.IsEnum)
            {
                return Enum.GetNames(this.PropertyType);
            }
            else if (this.PropertyType == typeof(bool))
            {
                string[] items = new string[2];
                if (converter != null && converter.CanConvertTo(typeof(string)))
                {
                    items[0] = (string)converter.ConvertTo(false, typeof(string));
                    items[1] = (string)converter.ConvertTo(true, typeof(string));
                }
                else
                {
                    items[0] = bool.FalseString;
                    items[1] = bool.TrueString;
                }
                return items;
            }
            return null;
        }
        protected virtual void SetupEditorAutoCompleteList(TextBoxDropDown editor)
        {
            if (this.PropertyType == null) return;
            TextBox textBox = editor.TextBox;
            TypeConverter converter = this.TypeConverter;
            //if (converter != null && converter.GetStandardValuesExclusive(this))
            //    editor.InternalReadOnly = true;
            //else
            //    editor.InternalReadOnly = false;
            string[] items = GetPopupListContent();
            if (items != null && items.Length > 0)
            {
                textBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                textBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
                textBox.AutoCompleteCustomSource.Clear();
                textBox.AutoCompleteCustomSource.AddRange(items);
                if (converter != null && converter.GetStandardValuesSupported() &&
                    converter.GetStandardValuesExclusive())
                    textBox.ReadOnly = true;
                else
                    textBox.ReadOnly = false;
            }
        }
        protected override void OnNodeDoubleClick(EventArgs e)
        {
            base.OnNodeDoubleClick(e);
            if (GetEffectiveReadOnly()) return;
            if (!SelectNextValue())
            {
                if (_Editor is TextBoxDropDown)
                {
                    ((TextBoxDropDown)_Editor).TextBox.SelectAll();
                    ((TextBoxDropDown)_Editor).Focus();
                }
                else if (_Editor is IPropertyValueEditor)
                    ((IPropertyValueEditor)_Editor).FocusEditor();
            }
        }
        public virtual bool SelectNextValue()
        {
            string[] listArray = GetPopupListContent();
            if (listArray == null || listArray.Length == 0) return false;
            List list = new List(listArray);
            string currentValue = this.EditCell.Text;
            if (string.IsNullOrEmpty(currentValue) || !list.Contains(currentValue))
            {
                currentValue = list[0];
            }
            else
            {
                int index = list.IndexOf(currentValue) + 1;
                if (index >= list.Count)
                    index = 0;
                currentValue = list[index];
            }
            Exception valueException = null;
            object value = GetValueFromString(currentValue, out valueException);
            if (valueException != null) return false;
            SetPropertyValue(this.GetTargetComponent(), value);
            RefreshPropertyValuesCheck();
            UpdateDisplayedValue();
            bool reportSuccess = AdvPropertyGrid.HighlightPropertyOnUpdate && !_IsUsingInlineEditor;
            if (reportSuccess)
            {
                this.IsSelectionVisible = false;
                StartHighlight(SuccessHighlightColor);
            }
            return true;
        }
        void EditorTextChanged(object sender, EventArgs e)
        {
            this.EditValueChanged = true;
        }
        protected virtual void EditorKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                CancelEdit();
                AdvTree.AdvTree tree = this.TreeControl;
                if (tree != null) tree.Focus();
                this.SetSelectedCell(this.Cells[0], eTreeAction.Keyboard);
            }
            else if (e.KeyCode == Keys.Enter)
            {
                if (ApplyEdit() && !(_IsDisposed || _IsDisposing))
                {
                    this.SetSelectedCell(this.Cells[0], eTreeAction.Keyboard);
                    AdvTree.AdvTree tree = this.TreeControl;
                    if (tree != null) tree.Focus();
                }
            }
            else if (e.KeyCode == Keys.Delete && !this.IsReadOnly && this.IsPropertyValueNullable && this.PropertyValue != null)
            {
                bool reset = true;
                TextBox textBox = sender as TextBox;
                if (textBox != null && textBox.SelectionLength != textBox.TextLength)
                    reset = false;
                if (reset)
                    ApplyValue(null, null);
            }
        }
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Down && e.Modifiers == Keys.Alt)
            {
                if (!ProcessEditorDropDownClick())
                {
                    TextBoxDropDown editor = _Editor as TextBoxDropDown;
                    if (editor != null && editor.ButtonDropDown.Visible && editor.DropDownControl != null && !editor.IsPopupOpen)
                        editor.IsPopupOpen = true;
                }
            }
            base.OnKeyDown(e);
        }
        protected virtual bool IsPropertyValueNullable
        {
            get
            {
                return !_Property.PropertyType.IsValueType;
            }
        }
        private bool _EditValueChanged = false;
        public bool EditValueChanged
        {
            get { return _EditValueChanged; }
            set
            {
                _EditValueChanged = value;
            }
        }
        protected override void OnDeselected(eTreeAction action)
        {
            if (this.IsEditing)
            {
                if (this.EditValueChanged && !IsReadOnly)
                    ApplyEdit();
                ExitEditorMode(action);
            }
            base.OnDeselected(action);
        }
        /// 
        /// Exits the editor mode.
        /// 
        /// Action that caused the editor mode exit.
        public virtual void ExitEditorMode(eTreeAction action)
        {
            if (!IsEditing) return;
            Control editor = _Editor as Control;
            if (!_IsUsingInlineEditor)
            {
                _Editor = null;
                this.EditCell.HostedControl = null;
            }
            if (editor is TextBoxDropDown && !_IsUsingInlineEditor)
            {
                TextBoxDropDown editorDropDown = (TextBoxDropDown)editor;
                if (editorDropDown.IsPopupOpen)
                    editorDropDown.CloseDropDown();
                if (editorDropDown.DropDownControl != null && !_UITypeEditorDropDownControl)
                {
                    Control c = editorDropDown.DropDownControl;
                    editorDropDown.DropDownControl = null;
                    c.Dispose();
                }
                editorDropDown.ButtonCustomClick -= EditorButtonCustomClick;
                editorDropDown.ButtonDropDownClick -= EditorButtonDropDownClick;
                editorDropDown.TextBox.KeyDown -= new KeyEventHandler(EditorKeyDown);
                editorDropDown.TextBox.TextChanged -= new EventHandler(EditorTextChanged);
                editorDropDown.Dispose();
            }
            else if (editor != null && !_IsUsingInlineEditor)
            {
                if (editor is IPropertyValueEditor)
                    ((IPropertyValueEditor)editor).EditValueChanged -= ValueEditorEditValueChanged;
                editor.Dispose();
            }
            if (_HighlightWorker != null && _HighlightWorker.IsBusy) _HighlightWorker.CancelAsync();
            IsEditing = false;
        }
        /// 
        /// Called when visual part of the node has changed due to the changes of its properties or properties of the cells contained by node.
        /// 
        internal override void OnDisplayChanged()
        {
            if (!IsDisposing && !IsDisposed)
                base.OnDisplayChanged();
        }
        /// 
        /// Cancel the edit changes and applies the old property value.
        /// 
        public virtual void CancelEdit()
        {
            if (!IsEditing) return;
            UpdateDisplayedValue();
            ClearErrorMarkings();
            _EditValueChanged = false;
            if (_HighlightWorker != null && _HighlightWorker.IsBusy) _HighlightWorker.CancelAsync();
        }
        protected virtual void RevertEditorValue()
        {
            Cell cell = this.EditCell;
            if (_Editor is TextBoxDropDown)
            {
                TextBoxDropDown editor = (TextBoxDropDown)_Editor;
                editor.Text = cell.Text;
                EditValueChanged = false;
                ElementStyle valueChangedStyle = this.ValueChangedStyle;
                if (valueChangedStyle != null && cell.StyleNormal == valueChangedStyle && valueChangedStyle.Font != null)
                    editor.TextBox.Font = valueChangedStyle.Font;
                else
                    editor.TextBox.Font = null;
            }
            else if (_Editor is IPropertyValueEditor)
            {
                IPropertyValueEditor editor = (IPropertyValueEditor)_Editor;
                if (!object.Equals(editor.EditValue, PropertyValue))  //if (editor.EditValue != PropertyValue)
                    editor.EditValue = PropertyValue;
                EditValueChanged = false;
                ElementStyle valueChangedStyle = this.ValueChangedStyle;
                if (valueChangedStyle != null && cell.StyleNormal == valueChangedStyle && valueChangedStyle.Font != null)
                    editor.EditorFont = valueChangedStyle.Font;
                else
                    editor.EditorFont = null;
            }
        }
        /// 
        /// Attempts to apply current edit value to the property.
        /// 
        public virtual bool ApplyEdit()
        {
            if (!IsEditing)
                throw new InvalidOperationException("Node is not in edit mode.");
            if (!EditValueChanged) return true;
            if (_Editor is TextBoxDropDown)
                return ApplyEdit(((TextBoxDropDown)_Editor).Text);
            else
                return ApplyEdit(((IPropertyValueEditor)_Editor).EditValue);
        }
        protected virtual bool ApplyEdit(object text)
        {
            Exception valueException = null;
            object value = null;
            if (text is string)
                value = GetValueFromString((string)text, out valueException);
            else
                value = text;
            return ApplyValue(value, valueException);
        }
        /// 
        /// Returns the full property path to the root of the selected object.
        /// 
        /// Full property path.
        public string GetPropertyPath()
        {
            string path = GetPropertyName();
            Node parent = this.Parent;
            while (parent != null)
            {
                PropertyNode propNode = parent as PropertyNode;
                if (propNode != null)
                {
                    if (propNode.PropertyDescriptor != null)
                        path = propNode.GetPropertyName() + "." + path;
                }
                parent = parent.Parent;
            }
            return path;
        }
        protected virtual bool ApplyValue(object value, Exception valueException)
        {
            bool valueApplied = false;
            if (GetPropertyValue(GetTargetComponent()) == value && valueException == null) return true;
            if (valueException == null)
            {
                AdvPropertyGrid grid = this.AdvPropertyGrid;
                if (grid != null)
                {
                    valueApplied = grid.InvokePropertyValueChanging(GetPropertyName(), value, _Property, GetPropertyPath());
                }
                if (!valueApplied)
                {
                    try
                    {
                        SetPropertyValue(this.GetTargetComponent(), value);
                        valueApplied = true;
                        if (_IsDisposed || _IsDisposing) return true;
                    }
                    catch (Exception e)
                    {
                        valueException = e;
                    }
                }
            }
            if (!valueApplied)
            {
                // Set error state...
                if (_PropertySettings == null || _PropertySettings.Image == null)
                    this.Image = GetErrorImage();
                this.IsSelectionVisible = false;
                // Get SuperTooltip to display error tip
                SuperTooltip tooltip = GetSuperTooltip();
                if (tooltip != null)
                    AttachErrorTooltip(tooltip, valueException, value);
                StartHighlight(ErrorHighlightColor);
            }
            else
            {
                // if for some reason property value was not set we'll return false
                if (value != null && !value.Equals(PropertyValue) && PropertyType.IsPrimitive) valueApplied = false;
                bool reportSuccess = AdvPropertyGrid.HighlightPropertyOnUpdate && !_IsUsingInlineEditor;
                if (_ErrorTooltipAttached)
                    reportSuccess = true;
                ClearErrorMarkings();
                UpdateDisplayedValue();
                if (reportSuccess)
                    this.IsSelectionVisible = false;
                if (reportSuccess && valueApplied)
                    StartHighlight(SuccessHighlightColor);
                _EditValueChanged = false;
                if (_Property != null && valueApplied)
                {
                    RefreshPropertyValuesCheck();
                }
            }
            return valueApplied;
        }
        private void RefreshPropertyValuesCheck()
        {
            if (_Property == null) return;
            RefreshPropertiesAttribute refreshAttribute = GetRefreshPropertiesAttribute();
            RefreshPropertiesAttribute parentRefresh = null;
            if (this.Parent is PropertyNode)
                parentRefresh = ((PropertyNode)this.Parent).GetRefreshPropertiesAttribute();
            if (parentRefresh != null && parentRefresh.RefreshProperties == RefreshProperties.All)
            {
                AdvPropertyGrid.RefreshPropertyValues(this.Parent);
            }
            else if (refreshAttribute != null)
            {
                if (refreshAttribute.RefreshProperties == RefreshProperties.Repaint)
                {
                    AdvPropertyGrid.RefreshPropertyValues();
                }
                else if (refreshAttribute.RefreshProperties == RefreshProperties.All)
                {
                    AdvPropertyGrid.RefreshProperties();
                }
            }
            if (this.Parent is PropertyNode)
                ((PropertyNode)this.Parent).UpdateDisplayedValue(false);
        }
        internal RefreshPropertiesAttribute GetRefreshPropertiesAttribute()
        {
            RefreshPropertiesAttribute refreshAttribute = _Property.Attributes[typeof(RefreshPropertiesAttribute)] as RefreshPropertiesAttribute;
            return refreshAttribute;
        }
        private Color ErrorHighlightColor
        {
            get
            {
                AdvPropertyGrid grid = AdvPropertyGrid;
                if (grid != null)
                {
                    return grid.Appearance.ErrorHighlightColor;
                }
                return ColorScheme.GetColor(0xD99694);
            }
        }
        private Color SuccessHighlightColor
        {
            get
            {
                AdvPropertyGrid grid = AdvPropertyGrid;
                if (grid != null)
                {
                    return grid.Appearance.SuccessHighlightColor;
                }
                return ColorScheme.GetColor(0x9BBB59);
            }
        }
        private void ClearErrorMarkings()
        {
            SuperTooltip tooltip = GetSuperTooltip();
            if (tooltip != null)
                EraseErrorTooltip(tooltip);
            if (_PropertySettings == null || _PropertySettings.Image == null)
                this.Image = null;
            if (_PropertySettings != null) UpdatePropertySettings();
        }
        private bool _ErrorTooltipAttached = false;
        private void AttachErrorTooltip(SuperTooltip tooltip, Exception valueException, object value)
        {
            SuperTooltipInfo info = new SuperTooltipInfo();
            info.HeaderText = this.Text;
            string s = GetErrorString();
            bool showTooltip = false;
            if (valueException is InvalidPropertyValueException && !string.IsNullOrEmpty(valueException.Message))
            {
                s = valueException.Message;
                showTooltip = true;
            }
            else if (valueException != null)
            {
                if (!s.EndsWith(" ")) s += " ";
                s += valueException.Message;
            }
            info.BodyText = s;
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null)
            {
                grid.InvokePrepareErrorSuperTooltip(info, GetPropertyName(), valueException, value);
            }
            tooltip.SetSuperTooltip(this, info);
            if (showTooltip)
            {
                // Show tooltip below the node
                Rectangle r = this.Cells[0].Bounds;
                AdvTree.AdvTree tree = this.TreeControl;
                if (tree != null)
                    r.Location = tree.PointToScreen(r.Location);
                tooltip.ShowTooltip(this, new Point(r.Right - 18, r.Bottom));
            }
            _ErrorTooltipAttached = true;
        }
        private string GetErrorString()
        {
            string s = "Error setting the value. ";
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null) s = grid.SystemText.ErrorSettingPropertyValueTooltip;
            IPropertyGridLocalizer localizer = this.PropertyGridLocalizer;
            if (localizer != null)
            {
                return localizer.GetErrorTooltipMessage(s) ?? s;
            }
            return s ?? "";
        }
        private void EraseErrorTooltip(SuperTooltip tooltip)
        {
            tooltip.HideTooltip();
            tooltip.SetSuperTooltip(this, null);
            _ErrorTooltipAttached = false;
        }
        private Image _ErrorImage = null;
        private Image GetErrorImage()
        {
            AdvPropertyGrid propertyGrid = this.AdvPropertyGrid;
            if (propertyGrid != null && propertyGrid.Appearance.PropertyValueErrorImage != null)
                return propertyGrid.Appearance.PropertyValueErrorImage;
            if (_ErrorImage == null)
                _ErrorImage = BarFunctions.LoadBitmap("SystemImages.ErrorIcon.png");
            return _ErrorImage;
        }
        private BackgroundWorker _HighlightWorker = null;
        private ElementStyle _HighlightStyle = null;
        /// 
        /// Starts fade background color style highlight for the property node.
        /// 
        /// Specifies the fade background color.
        public void StartHighlight(Color color)
        {
            if (_HighlightWorker == null)
            {
                _HighlightWorker = new BackgroundWorker();
                _HighlightWorker.WorkerSupportsCancellation = true;
                _HighlightWorker.DoWork += new DoWorkEventHandler(HighlightWorkerDoWork);
                _HighlightWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(HighlightWorkerCompleted);
                if (this.Style != null)
                {
                    _HighlightStyle = this.Style.Copy();
                }
                else
                {
                    AdvTree.AdvTree tree = this.TreeControl;
                    if (tree != null && tree.NodeStyle != null)
                        _HighlightStyle = tree.NodeStyle.Copy();
                    else
                        _HighlightStyle = new ElementStyle();
                }
            }
            else if (_HighlightWorker.IsBusy)
            {
                _HighlightWorker.CancelAsync();
                return;
            }
            _HighlightStyle.BackColor = color;
            this.Style = _HighlightStyle;
            _HighlightWorker.RunWorkerAsync(this.TreeControl);
        }
        private SuperTooltip GetSuperTooltip()
        {
            AdvPropertyGrid grid = this.AdvPropertyGrid;
            if (grid != null) return grid.SuperTooltip;
            return null;
        }
        internal void SetHelpTooltip(SuperTooltip superTooltip)
        {
            string description = GetDescriptionAttributeValue();
            if (string.IsNullOrEmpty(description))
                superTooltip.SetSuperTooltip(this, null);
            else
            {
                SuperTooltipInfo info = new SuperTooltipInfo(this.Text, "", description, null, null, eTooltipColor.System, true, false, Size.Empty);
                superTooltip.SetSuperTooltip(this, info);
            }
        }
        private void HighlightWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Style = GetDefaultStyle();
            this.IsSelectionVisible = true;
        }
        private void HighlightWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 255; i > 0; i -= 25)
            {
                if (e.Cancel) break;
                Control control = e.Argument as Control;
                if (control.IsHandleCreated && !control.IsDisposed)
                    control.BeginInvoke(new ChangeHighlightStyleDelegate(ChangeHighlightStyle), new object[] { i });
                try
                {
                    using (
                                        System.Threading.ManualResetEvent wait =
                                            new System.Threading.ManualResetEvent(false))
                        wait.WaitOne(80);
                    //Thread.Sleep(80);
                }
                catch 
                {
                    break;
                }
            }
        }
        private void ChangeHighlightStyle(int alpha)
        {
            _HighlightStyle.BackColor = Color.FromArgb(alpha, _HighlightStyle.BackColor.R, _HighlightStyle.BackColor.G, _HighlightStyle.BackColor.B);
        }
        private delegate void ChangeHighlightStyleDelegate(int alpha);
        protected virtual object GetValueFromString(string text, out Exception exception)
        {
            object value = null;
            exception = null;
            if (_PropertySettings != null && _PropertySettings.HasConvertFromStringToPropertyValueHandler)
            {
                ConvertValueEventArgs args = new ConvertValueEventArgs(text, null, GetPropertyName(), GetTargetComponent(), PropertyDescriptor);
                try
                {
                    _PropertySettings.InvokeConvertFromStringToPropertyValue(args);
                }
                catch (Exception e)
                {
                    exception = e;
                }
                if (args.IsConverted)
                    return args.TypedValue;
            }
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null && grid.HasConvertFromStringToPropertyValueHandler)
            {
                ConvertValueEventArgs args = new ConvertValueEventArgs(text, null, GetPropertyName(), GetTargetComponent(), PropertyDescriptor);
                try
                {
                    grid.InvokeConvertFromStringToPropertyValue(args);
                }
                catch (Exception e)
                {
                    exception = e;
                }
                if (args.IsConverted)
                    return args.TypedValue;
            }
            TypeConverter conv = this.TypeConverter;
            try
            {
                value = conv.ConvertFromString(this, text);
            }
            catch (Exception e)
            {
                exception = e;
            }
            return value;
        }
        protected virtual void SetPropertyValue(object target, object value)
        {
            PropertyDescriptor propertyDescriptor = GetPropertyDescriptor();
            if (propertyDescriptor == null)
            {
                return;
            }
            if (_IsMultiObject)
            {
                TypeConverter converter = this.TypeConverter;
                object[] targets = (object[])target;
                foreach (object item in targets)
                {
                    if (propertyDescriptor.PropertyType.IsAssignableFrom(item.GetType()))
                        SetPropertyValueCore(item, value, propertyDescriptor);
                    else
                    {
                        PropertyDescriptor desc2 = PropertyParser.GetProperty(propertyDescriptor.Name, item, converter.GetPropertiesSupported(this) ? converter : null);
                        if (desc2 == null)
                            desc2 = PropertyParser.GetProperty(propertyDescriptor.Name, item, null);
                        SetPropertyValueCore(item, value, desc2);
                    }
                }
            }
            else
            {
                SetPropertyValueCore(target, value, propertyDescriptor);
            }
        }
        private void ValidatePropertyValue(object target, object value, PropertyDescriptor propertyDescriptor)
        {
            AdvPropertyGrid pg = this.AdvPropertyGrid;
            if (pg == null) return;
            if (!pg.HasValidatePropertyValueHandlers) return;
            ValidatePropertyValueEventArgs args = new ValidatePropertyValueEventArgs(propertyDescriptor.Name, value, target);
            pg.InvokeValidatePropertyValue(args);
            if (args.Cancel)
                throw new InvalidPropertyValueException(args.Message);
        }
        protected virtual void SetPropertyValueCore(object target, object value, PropertyDescriptor propertyDescriptor)
        {
            ValidatePropertyValue(target, value, propertyDescriptor);
            bool useCreateInstance = false;
            PropertyNode parent = this.Parent as PropertyNode;
            if (parent != null)
            {
                TypeConverter parentConverter = parent.TypeConverter;
                if (parentConverter != null && parentConverter.GetCreateInstanceSupported(this))
                    useCreateInstance = true;
            }
            if (useCreateInstance)
            {
                if (target is ICustomTypeDescriptor)
                {
                    target = ((ICustomTypeDescriptor)target).GetPropertyOwner(propertyDescriptor);
                }
                object valueOwner = parent.GetTargetComponent();
                TypeConverter parentTypeConverter = parent.TypeConverter;
                PropertyDescriptorCollection properties = parentTypeConverter.GetProperties(parent, valueOwner);
                Dictionary propertyValues = new Dictionary(properties.Count);
                object newValueInstance = null;
                for (int i = 0; i < properties.Count; i++)
                {
                    string propertyName = GetPropertyName();
                    if (propertyName != null && propertyName.Equals(properties[i].Name))
                    {
                        propertyValues[properties[i].Name] = value;
                    }
                    else
                    {
                        propertyValues[properties[i].Name] = properties[i].GetValue(target);
                    }
                }
                try
                {
                    newValueInstance = parentTypeConverter.CreateInstance(parent, propertyValues);
                }
                catch (Exception exception)
                {
                    if (string.IsNullOrEmpty(exception.Message))
                    {
                        throw new TargetInvocationException("Exception Creating New Instance Of Object For Property " + this.Text + " " + parent.PropertyType.FullName + " " + exception.ToString(), exception);
                    }
                    throw;
                }
                if (newValueInstance != null)
                {
                    parent.PropertyValue = newValueInstance;
                }
            }
            else
            {
                if (target is ICustomTypeDescriptor)
                {
                    target = ((ICustomTypeDescriptor)target).GetPropertyOwner(propertyDescriptor);
                }
                try
                {
                    propertyDescriptor.SetValue(target, value);
                }
                catch
                {
                    throw;
                }
            }
            AdvPropertyGrid grid = this.AdvPropertyGrid;
            if (grid != null)
                grid.InvokePropertyValueChanged(GetPropertyName(), value, null);
        }
        private bool _IsDisposing;
        internal bool IsDisposing
        {
            get { return _IsDisposing; }
            set
            {
                _IsDisposing = value;
            }
        }
        internal bool IsDisposed
        {
            get
            {
                return _IsDisposed;
            }
        }
        private bool _IsDisposed = false;
        protected override void Dispose(bool disposing)
        {
            _IsDisposed = true;
            if (this.IsEditing)
                CancelEdit();
            BackgroundWorker worker = _HighlightWorker;
            _HighlightWorker = null;
            if (worker != null) worker.Dispose();
            if (_ErrorImage != null) _ErrorImage.Dispose();
            base.Dispose(disposing);
        }
        protected virtual AdvPropertyGrid AdvPropertyGrid
        {
            get
            {
                AdvTree.AdvTree tree = this.TreeControl;
                if (tree == null) return null;
                Control parent = tree.Parent;
                while (parent != null)
                {
                    if (parent is AdvPropertyGrid) return (AdvPropertyGrid)parent;
                    parent = parent.Parent;
                }
                return null;
            }
        }
        internal virtual void OnLoaded()
        {
            UpdateChildProperties();
            UpdatePropertySettings();
        }
        private void UpdateChildProperties()
        {
            if (HasChildProperties)
            {
                this.ExpandVisibility = eNodeExpandVisibility.Visible;
                if (this.Expanded)
                    LoadChildProperties();
            }
            else
            {
                if (this.HasChildNodes)
                {
                    AdvPropertyGrid propertyGrid = AdvPropertyGrid;
                    foreach (Node child in this.Nodes)
                        AdvPropertyGrid.ClearPropertyNode(child, propertyGrid);
                    this.Nodes.Clear();
                }
                this.Expanded = false;
                this.ExpandVisibility = eNodeExpandVisibility.Auto;
            }
        }
        public bool HasChildProperties
        {
            get
            {
                TypeConverter converter = this.TypeConverter;
                if (converter != null && converter.GetPropertiesSupported())
                {
                    PropertyDescriptorCollection childProps = PropertyParser.GetProperties(this, AttributeFilter, this.PropertyValue, converter.GetPropertiesSupported(this) ? converter : null);
                    if (childProps != null && childProps.Count > 0)
                        return true;
                }
                return false;
            }
        }
        protected virtual Attribute[] AttributeFilter
        {
            get
            {
                AdvPropertyGrid grid = AdvPropertyGrid;
                if (grid != null)
                {
                    Attribute[] attributes = new Attribute[grid.BrowsableAttributes.Count];
                    grid.BrowsableAttributes.CopyTo(attributes, 0);
                    return attributes;
                }
                return null;
            }
        }
        protected virtual void LoadChildProperties()
        {
            string lastSelectedProperty = null;
            AdvTree.AdvTree tree = this.TreeControl;
            ePropertySort childPropertySort = ePropertySort.Alphabetical;
            if (tree != null)
            {
                tree.BeginUpdate();
                if (tree.Parent is AdvPropertyGrid)
                    childPropertySort = ((AdvPropertyGrid)tree.Parent).SubPropertiesDefaultSort;
            }
            try
            {
                if (this.HasChildNodes)
                {
                    if (tree != null && tree.SelectedNode != null && this.Nodes.Contains(tree.SelectedNode))
                        lastSelectedProperty = tree.SelectedNode.Text;
                }
                ClearChildNodes();
                TypeConverter converter = this.TypeConverter;
                if (converter != null && converter.GetPropertiesSupported())
                {
                    Attribute[] attributes = AttributeFilter;
                    List ignoredProperties = this.IgnoredProperties;
                    List ignoredCategories = this.IgnoredCategories;
                    IPropertyGridLocalizer localizer = this.PropertyGridLocalizer;
                    PropertyDescriptorCollection childProps = PropertyParser.GetProperties(this, attributes, this.PropertyValue, converter.GetPropertiesSupported(this) ? converter : null);
                    PropertyNodeFactory factory = this.NodeFactory;
                    if (childProps != null && childProps.Count > 0)
                    {
                        PropertyParser parser = new PropertyParser(
                                                    this,
                                                    this.PropertyValue,
                                                    attributes,
                                                    factory,
                                                    ignoredProperties,
                                                    ignoredCategories,
                                                    localizer,
                                                    this.PropertySettingsCollection);
                        parser.HelpType = AdvPropertyGrid.HelpType;
                        parser.TypeConverter = converter.GetPropertiesSupported(this) ? converter : null;
                        parser.Parse(this.Nodes, childPropertySort, GetSuperTooltip());
                    }
                }
                if (!string.IsNullOrEmpty(lastSelectedProperty) && this.HasChildNodes && tree != null)
                {
                    foreach (Node item in this.Nodes)
                    {
                        if (item.Text == lastSelectedProperty)
                        {
                            tree.SelectedNode = item;
                            break;
                        }
                    }
                }
            }
            finally
            {
                if (tree != null) tree.EndUpdate();
            }
        }
        private void ClearChildNodes()
        {
            if (!this.HasChildNodes) return;
            AdvPropertyGrid propertyGrid = AdvPropertyGrid;
            foreach (Node item in this.Nodes)
            {
                AdvPropertyGrid.ClearPropertyNode(item, propertyGrid);
                if (item.IsSelected && propertyGrid.PropertyTree != null)
                    propertyGrid.PropertyTree.SelectedNode = null;
            }
            this.Nodes.Clear();
        }
        internal PropertyNodeFactory NodeFactory
        {
            get
            {
                AdvPropertyGrid grid = this.AdvPropertyGrid;
                if (grid != null)
                    return grid.GetPropertyNodeFactory();
                else
                    return new PropertyNodeFactory(null);
            }
        }
        public IPropertyGridLocalizer PropertyGridLocalizer
        {
            get
            {
                return AdvPropertyGrid;
            }
        }
        public PropertySettingsCollection PropertySettingsCollection
        {
            get
            {
                AdvPropertyGrid grid = AdvPropertyGrid;
                if (grid != null) return grid.PropertySettings;
                return null;
            }
        }
        private PropertySettings _PropertySettings = null;
        /// 
        /// Gets or sets the property settings that are applied to this property node.
        /// 
        public PropertySettings PropertySettings
        {
            get { return _PropertySettings; }
            set
            {
                if (_PropertySettings == value) return;
                if (_PropertySettings != null)
                    _PropertySettings.PropertyChanged -= new PropertyChangedEventHandler(PropertySettingsChanged);
                _PropertySettings = value;
                if (_PropertySettings != null)
                    _PropertySettings.PropertyChanged += new PropertyChangedEventHandler(PropertySettingsChanged);
                UpdateValueInlineEditor();
            }
        }
        private void PropertySettingsChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName != PropertySettings.NamePropertyName && e.PropertyName != PropertySettings.NamePropertyDescriptor)
                UpdatePropertySettings();
            if (e.PropertyName == "ValueEditor")
                UpdateValueInlineEditor();
        }
        private bool IsCollection
        {
            get
            {
                if (_Property == null) return false;
                if (_Property.PropertyType.GetInterface("IList") != null && !_Property.PropertyType.IsArray && _Property.IsReadOnly)
                    return true;
                return false;
            }
        }
        /// 
        /// Applies PropertySettings to this node.
        /// 
        public virtual void UpdatePropertySettings()
        {
            bool parentCreateInstanceSupported = false;
            TypeConverter parentConverter = null;
            if (this.Parent is PropertyNode)
            {
                PropertyNode parent = (PropertyNode)this.Parent;
                parentConverter = parent.TypeConverter;
                if (parentConverter != null && parentConverter.GetCreateInstanceSupported(this))
                    parentCreateInstanceSupported = true;
            }
            if (_PropertySettings == null)
            {
                if (!this.Visible) this.Visible = true;
                bool readOnlyAtt = false;
                if (parentConverter == null | !parentCreateInstanceSupported)
                    readOnlyAtt = PropertyParser.GetReadOnlyAttribute(_Property, this.GetTargetComponent());
                if (readOnlyAtt && !IsCollection)
                    this.IsReadOnly = readOnlyAtt;
                else if (parentCreateInstanceSupported || IsUsingPropertyEditor())
                    this.IsReadOnly = false;
                this.Text = GetDefaultPropertyName();
                this.ImageAlignment = eCellPartAlignment.FarCenter;
                this.Image = null;
                if (!_ErrorTooltipAttached)
                {
                    SuperTooltip tooltip = GetSuperTooltip();
                    if (tooltip != null)
                    {
                        tooltip.SetSuperTooltip(this, null);
                    }
                }
                return;
            }
            if (this.Visible != _PropertySettings.Visible)
                this.Visible = _PropertySettings.Visible;
            if (this.IsReadOnly != _PropertySettings.ReadOnly)
                this.IsReadOnly = _PropertySettings.ReadOnly;
            else if (!_ErrorTooltipAttached && !this.IsReadOnly)
                this.Style = GetDefaultStyle();
            if (!_ErrorTooltipAttached && this.IsReadOnly && _PropertySettings.ReadOnlyTooltip != null)
            {
                SuperTooltip tooltip = GetSuperTooltip();
                if (tooltip != null)
                {
                    tooltip.SetSuperTooltip(this, _PropertySettings.ReadOnlyTooltip);
                }
            }
            if (_PropertySettings.Image != null)
            {
                this.Image = _PropertySettings.Image;
                this.ImageAlignment = _PropertySettings.ImageAlignment;
            }
            else
            {
                this.ImageAlignment = eCellPartAlignment.FarCenter;
                this.Image = null;
            }
            if (!string.IsNullOrEmpty(_PropertySettings.DisplayName))
                this.Text = _PropertySettings.DisplayName;
            else
                this.Text = GetDefaultPropertyName();
            if (!_ErrorTooltipAttached && _PropertySettings.Tooltip != null && !(_PropertySettings.ReadOnly && _PropertySettings.ReadOnlyTooltip != null))
            {
                SuperTooltip tooltip = GetSuperTooltip();
                if (tooltip != null)
                {
                    tooltip.SetSuperTooltip(this, _PropertySettings.Tooltip);
                }
            }
        }
        private string GetDefaultPropertyName()
        {
            string text = _Property.DisplayName;
            IPropertyGridLocalizer localizer = this.PropertyGridLocalizer;
            if (localizer != null)
            {
                string name = localizer.GetPropertyName(_Property.Name);
                if (!string.IsNullOrEmpty(name)) text = name;
            }
            return text;
        }
        public List IgnoredCategories
        {
            get
            {
                List categories = new List();
                AdvPropertyGrid grid = AdvPropertyGrid;
                if (grid != null)
                {
                    categories.AddRange(grid.IgnoredCategories);
                }
                return categories;
            }
        }
        public List IgnoredProperties
        {
            get
            {
                List props = new List();
                AdvPropertyGrid grid = AdvPropertyGrid;
                if (grid != null)
                {
                    props.AddRange(grid.IgnoredProperties);
                }
                return props;
            }
        }
        protected override void OnExpandChanging(bool expanded, eTreeAction action)
        {
            if (expanded)
            {
                LoadChildProperties();
            }
            base.OnExpandChanging(expanded, action);
        }
        private bool _IsMultiObject = false;
        /// 
        /// Gets or sets whether property node represents property for multiple objects.
        /// 
        public bool IsMultiObject
        {
            get { return _IsMultiObject; }
            internal set
            {
                _IsMultiObject = value;
            }
        }
        protected override void OnKeyboardCopy(KeyEventArgs args)
        {
            Clipboard.SetText(this.EditCell.Text);
            base.OnKeyboardCopy(args);
        }
        protected override void OnKeyboardPaste(KeyEventArgs args)
        {
            if (Clipboard.ContainsText() && !this.IsReadOnly)
            {
                ApplyEdit(Clipboard.GetText());
            }
            base.OnKeyboardPaste(args);
        }
        private bool _IsPassword = false;
        /// 
        /// Gets or sets whether property is password property which value is not displayed as plain text.
        /// 
        public bool IsPassword
        {
            get
            {
                return _IsPassword;
            }
            set
            {
                _IsPassword = value;
            }
        }
        #endregion
        #region ITypeDescriptorContext Members
        public virtual IComponent Component
        {
            get
            {
                object valueOwner = GetTargetComponent();
                if (valueOwner is IComponent)
                {
                    return (IComponent)valueOwner;
                }
                return null;
            }
        }
        IContainer ITypeDescriptorContext.Container
        {
            get
            {
                IComponent component = this.Component;
                if (component != null)
                {
                    ISite site = component.Site;
                    if (site != null)
                    {
                        return site.Container;
                    }
                }
                return null;
            }
        }
        object ITypeDescriptorContext.Instance
        {
            get { return GetTargetComponent(); }
        }
        void ITypeDescriptorContext.OnComponentChanged()
        {
        }
        bool ITypeDescriptorContext.OnComponentChanging()
        {
            return true;
        }
        PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor
        {
            get { return GetPropertyDescriptor(); }
        }
        #endregion
        #region IServiceProvider Members
        object IServiceProvider.GetService(Type serviceType)
        {
            //Console.WriteLine(serviceType);
            if (serviceType == typeof(PropertyNode) || serviceType == typeof(IWindowsFormsEditorService))
            {
                return this;
            }
            AdvPropertyGrid grid = AdvPropertyGrid;
            if (grid != null)
            {
                if (grid.Site != null) return grid.Site.GetService(serviceType);
                if (grid.Parent != null && grid.Parent.Site != null) return grid.Parent.Site.GetService(serviceType);
            }
            return null;
        }
        #endregion
        #region IWindowsFormsEditorService Members
        void IWindowsFormsEditorService.CloseDropDown()
        {
            TextBoxDropDown editor = _Editor as TextBoxDropDown;
            if (editor != null && editor.IsPopupOpen)
                editor.CloseDropDown();
        }
        private bool _UITypeEditorDropDownControl = false;
        [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, ExactSpelling = true)]
        private static extern int MsgWaitForMultipleObjectsEx(int nCount, IntPtr pHandles, int dwMilliseconds, int dwWakeMask, int dwFlags);
        void IWindowsFormsEditorService.DropDownControl(Control control)
        {
            Type type = typeof(Application);
            TextBoxDropDown editor = _Editor as TextBoxDropDown;
            MethodInfo mi = type.GetMethod("DoEventsModal", BindingFlags.Static | BindingFlags.NonPublic);
            if (mi == null || editor == null) return;
            editor.DropDownControl = control;
            _UITypeEditorDropDownControl = true;
            editor.ShowDropDown();
            while (editor != null && editor.IsPopupOpen)
            {
                mi.Invoke(null, null);
                MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 250, 0xff, 4);
            }
            if (editor != null)
            {
                editor.ProcessMouseUpOnGroup();
                editor.DropDownControl = null;
            }
            _UITypeEditorDropDownControl = false;
        }
        DialogResult IWindowsFormsEditorService.ShowDialog(Form dialog)
        {
            return dialog.ShowDialog();
        }
        #endregion
    }
    /// 
    /// Defines an interface that is implemented by the control that will be used by AdvPropertyGrid control to edit property value.
    /// 
    public interface IPropertyValueEditor
    {
        /// 
        /// Gets or sets the font used by the edit part of the control. Font might be used to visually indicate that property value has changed. Implementing this property is optional.
        /// 
        Font EditorFont { get;set;}
        /// 
        /// Gets whether the edit part of the control is focused.
        /// 
        bool IsEditorFocused { get;}
        /// 
        /// Focus the edit part of the control.
        /// 
        void FocusEditor();
        /// 
        /// Gets or sets the value being edited.
        /// 
        object EditValue { get;set;}
        /// 
        /// Occurs when EditValue changes. Raising this even will cause the property value to be updated with the EditValue.
        /// 
        event EventHandler EditValueChanged;
    }
    /// 
    /// Defines exception which is thrown when property value fails the validation in AdvPropertyGrid.ValidatePropertyValue event.
    /// 
    public class InvalidPropertyValueException : Exception
    {
        /// 
        /// Initializes a new instance of the InvalidPropertyValueException class.
        /// 
        public InvalidPropertyValueException(string message)
            : base(message)
        {
        }
    }
}
#endif