protected virtual bool ShowEnumField(PropertyGridProperty property, Type type, string name, out string displayName)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            FieldInfo fi = type.GetField(name, BindingFlags.Static | BindingFlags.Public);

            displayName = fi.Name;
            var ba = fi.GetAttribute <BrowsableAttribute>();

            if (ba != null && !ba.Browsable)
            {
                return(false);
            }

            var da = fi.GetAttribute <DescriptionAttribute>();

            if (da != null && !string.IsNullOrWhiteSpace(da.Description))
            {
                displayName = da.Description;
            }
            return(true);
        }
        public virtual bool?ShowEditor(PropertyGridProperty property, object parameter)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            Window editor = GetEditor(property, parameter);

            if (editor != null)
            {
                bool?ret;
                var  go = property.DataProvider.Data as IPropertyGridObject;
                if (go != null)
                {
                    if (go.TryShowEditor(property, editor, out ret))
                    {
                        return(ret);
                    }

                    RefreshSelectedObject(editor);
                }

                ret = editor.ShowDialog();
                if (go != null)
                {
                    go.EditorClosed(property, editor);
                }
                return(ret);
            }
            return(null);
        }
        public static object EnumToObject(PropertyGridProperty property, object value)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            if (value != null && property.PropertyType.IsEnum)
            {
                return(Extensions.EnumToObject(property.PropertyType, value));
            }

            if (value != null && value.GetType().IsEnum)
            {
                return(Extensions.EnumToObject(value.GetType(), value));
            }

            if (property.PropertyType != typeof(string))
            {
                return(ConversionService.ChangeType(value, property.PropertyType));
            }

            var options = PropertyGridOptionsAttribute.FromProperty(property);

            if (options == null)
            {
                return(ConversionService.ChangeType(value, property.PropertyType));
            }

            return(EnumToObject(options, property.PropertyType, value));
        }
Esempio n. 4
0
        protected virtual bool Filter(PropertyGridDataTemplate template, PropertyGridProperty property)
        {
            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            // check various filters
            if (template.IsCollection.HasValue && template.IsCollection.Value != property.IsCollection)
            {
                return(true);
            }

            if (template.IsCollectionItemValueType.HasValue && template.IsCollectionItemValueType.Value != property.IsCollectionItemValueType)
            {
                return(true);
            }

            if (template.IsValueType.HasValue && template.IsValueType.Value != property.IsValueType)
            {
                return(true);
            }

            if (template.IsReadOnly.HasValue && template.IsReadOnly.Value != property.IsReadOnly)
            {
                return(true);
            }

            if (template.IsError.HasValue && template.IsError.Value != property.IsError)
            {
                return(true);
            }

            if (template.IsValid.HasValue && template.IsValid.Value != property.IsValid)
            {
                return(true);
            }

            if (template.IsFlagsEnum.HasValue && template.IsFlagsEnum.Value != property.IsFlagsEnum)
            {
                return(true);
            }

            if (template.Category != null && !property.Category.EqualsIgnoreCase(template.Category))
            {
                return(true);
            }

            if (template.Name != null && !property.Name.EqualsIgnoreCase(template.Name))
            {
                return(true);
            }

            return(false);
        }
        protected virtual void ScanProperties()
        {
            Properties.Clear();
            List <PropertyGridProperty> props = new List <PropertyGridProperty>();

            foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(Data))
            {
                if (!descriptor.IsBrowsable)
                {
                    continue;
                }

                PropertyGridProperty property = CreateProperty(descriptor);
                if (property != null)
                {
                    props.Add(property);
                }
            }

            IPropertyGridObject pga = Data as IPropertyGridObject;

            if (pga != null)
            {
                pga.FinalizeProperties(this, props);
            }

            props.Sort();
            foreach (PropertyGridProperty property in props)
            {
                Properties.Add(property);
            }
        }
        public virtual PropertyGridProperty AddProperty(string propertyName)
        {
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }

            PropertyGridProperty prop = Properties.FirstOrDefault(p => p.Name == propertyName);

            if (prop != null)
            {
                return(prop);
            }

            PropertyDescriptor desc = TypeDescriptor.GetProperties(Data).OfType <PropertyDescriptor>().FirstOrDefault(p => p.Name == propertyName);

            if (desc != null)
            {
                prop = CreateProperty(desc);
                if (prop != null)
                {
                    Properties.Add(prop);
                }
            }
            return(prop);
        }
        protected virtual void OnGuidCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            var property = PropertyGridProperty.FromEvent(e);

            if (property != null && (property.PropertyType == typeof(Guid) || property.PropertyType == typeof(Guid?)))
            {
                e.CanExecute = true;
            }
        }
        protected virtual void OnEditorWindowSaveExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            Window window             = (Window)sender;
            PropertyGridProperty prop = window.DataContext as PropertyGridProperty;

            if (prop != null)
            {
                prop.Executed(sender, e);
            }
        }
Esempio n. 9
0
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                PropertyGridProperty property = value as PropertyGridProperty;

                if (property != null)
                {
                    return(Extension.BuildItems(property, targetType, parameter, culture));
                }

                return(value);
            }
        protected virtual void Describe(PropertyGridProperty property, PropertyDescriptor descriptor)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            if (descriptor == null)
            {
                throw new ArgumentNullException("descriptor");
            }

            property.Descriptor   = descriptor;
            property.Name         = descriptor.Name;
            property.PropertyType = descriptor.PropertyType;

            // unset by default. conversion service does the default job
            //property.Converter = descriptor.Converter;

            property.Category    = string.IsNullOrWhiteSpace(descriptor.Category) || descriptor.Category.EqualsIgnoreCase(CategoryAttribute.Default.Category) ? Grid.DefaultCategoryName : descriptor.Category;
            property.IsReadOnly  = descriptor.IsReadOnly;
            property.Description = descriptor.Description;
            property.DisplayName = descriptor.DisplayName;
            if (property.DisplayName == descriptor.Name)
            {
                property.DisplayName = DecamelizationService.Decamelize(property.DisplayName);
            }

            property.IsEnum      = descriptor.PropertyType.IsEnum;
            property.IsFlagsEnum = descriptor.PropertyType.IsEnum && Extensions.IsFlagsEnum(descriptor.PropertyType);

            DefaultValueAttribute att = descriptor.GetAttribute <DefaultValueAttribute>();

            property.HasDefaultValue = att != null;
            property.DefaultValue    = att != null ? att.Value : null;

            PropertyGridOptionsAttribute options = descriptor.GetAttribute <PropertyGridOptionsAttribute>();

            if (options != null)
            {
                if (options.SortOrder != 0)
                {
                    property.SortOrder = options.SortOrder;
                }

                property.IsEnum      = options.IsEnum;
                property.IsFlagsEnum = options.IsFlagsEnum;
            }

            AddDynamicProperties(descriptor.Attributes.OfType <PropertyGridAttribute>(), property.Attributes);
            AddDynamicProperties(descriptor.PropertyType.GetAttributes <PropertyGridAttribute>(), property.TypeAttributes);
        }
        public virtual PropertyGridProperty CreateProperty(PropertyDescriptor descriptor)
        {
            if (descriptor == null)
            {
                throw new ArgumentNullException("descriptor");
            }

            bool forceReadWrite = false;
            PropertyGridProperty         property = null;
            PropertyGridOptionsAttribute options  = descriptor.GetAttribute <PropertyGridOptionsAttribute>();

            if (options != null)
            {
                forceReadWrite = options.ForceReadWrite;
                if (options.PropertyType != null)
                {
                    property = (PropertyGridProperty)Activator.CreateInstance(options.PropertyType, this);
                }
            }

            if (property == null)
            {
                options = descriptor.PropertyType.GetAttribute <PropertyGridOptionsAttribute>();
                if (options != null)
                {
                    if (!forceReadWrite)
                    {
                        forceReadWrite = options.ForceReadWrite;
                    }
                    if (options.PropertyType != null)
                    {
                        property = (PropertyGridProperty)Activator.CreateInstance(options.PropertyType, this);
                    }
                }
            }

            if (property == null)
            {
                property = CreateProperty();
            }

            Describe(property, descriptor);
            if (forceReadWrite)
            {
                property.IsReadOnly = false;
            }
            property.OnDescribed();
            property.RefreshValueFromDescriptor();
            return(property);
        }
        protected virtual void OnEditorWindowCloseCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            Window window             = (Window)sender;
            PropertyGridProperty prop = window.DataContext as PropertyGridProperty;

            if (prop != null)
            {
                prop.CanExecute(sender, e);
                if (e.Handled)
                {
                    return;
                }
            }
            e.CanExecute = true;
        }
        protected virtual void OnEditorWindowCloseExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            Window window             = (Window)sender;
            PropertyGridProperty prop = window.DataContext as PropertyGridProperty;

            if (prop != null)
            {
                prop.Executed(sender, e);
                if (e.Handled)
                {
                    return;
                }
            }
            window.Close();
        }
        protected virtual void OnSourcePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e == null || e.PropertyName == null)
            {
                return;
            }

            PropertyGridProperty property = GetProperty(e.PropertyName);

            if (property != null)
            {
                property.RefreshValueFromDescriptor();
                OnPropertyChanged(this, CreateEventArgs(property));
            }
        }
        public virtual bool?ShowEditor(string propertyName, object parameter)
        {
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }

            PropertyGridProperty property = GetProperty(propertyName);

            if (property == null)
            {
                return(null);
            }

            return(ShowEditor(property, parameter));
        }
Esempio n. 16
0
        public static PropertyGridOptionsAttribute FromProperty(PropertyGridProperty property)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            PropertyGridOptionsAttribute att = property.Options;

            if (att != null)
            {
                return(att);
            }

            if (property.Descriptor != null)
            {
                att = property.Descriptor.GetAttribute <PropertyGridOptionsAttribute>();
            }
            return(att);
        }
        protected virtual bool CollectionEditorHasOnlyOneColumn(PropertyGridProperty property)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            var att = PropertyGridOptionsAttribute.FromProperty(property);

            if (att != null)
            {
                return(att.CollectionEditorHasOnlyOneColumn);
            }

            if (_collectionEditorHasOnlyOneColumnList.Contains(property.CollectionItemPropertyType))
            {
                return(true);
            }

            return(!PropertyGridDataProvider.HasProperties(property.CollectionItemPropertyType));
        }
        protected virtual void OnBrowseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var browse = new RoutedEventArgs(BrowseEvent, e.OriginalSource);

            RaiseEvent(browse);
            if (browse.Handled)
            {
                return;
            }

            var property = PropertyGridProperty.FromEvent(e);

            if (property != null)
            {
                property.Executed(sender, e);
                if (!e.Handled)
                {
                    ShowEditor(property, e.Parameter);
                }
            }
        }
        protected virtual void OnSourcePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e == null || e.PropertyName == null)
            {
                return;
            }

            PropertyGridProperty property = GetProperty(e.PropertyName);

            if (property != null)
            {
                bool forceRaise = false;
                var  options    = PropertyGridOptionsAttribute.FromProperty(property);
                if (options != null)
                {
                    forceRaise = options.ForcePropertyChanged;
                }

                property.RefreshValueFromDescriptor(true, forceRaise, true);
                OnPropertyChanged(this, CreateEventArgs(property));
            }
        }
Esempio n. 20
0
        public static DataTemplate SelectTemplate(PropertyGridProperty property, object item, DependencyObject container)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            PropertyGridOptionsAttribute att = FromProperty(property);

            if (att == null)
            {
                return(null);
            }

            if (att.EditorDataTemplateResourceKey != null)
            {
                if (Application.Current != null)
                {
                    DataTemplate dt = (DataTemplate)Application.Current.TryFindResource(att.EditorDataTemplateResourceKey);
                    if (dt != null)
                    {
                        return(dt);
                    }
                }

                var fe = container as FrameworkElement;
                if (fe != null)
                {
                    var dt = (DataTemplate)fe.TryFindResource(att.EditorDataTemplateResourceKey);
                    if (dt != null)
                    {
                        return(dt);
                    }
                }

                return(null);
            }

            if (att.EditorType != null)
            {
                object editor = Activator.CreateInstance(att.EditorType);
                if (att.EditorDataTemplateSelectorPropertyPath != null)
                {
                    var dts = (DataTemplateSelector)DataBindingEvaluator.GetPropertyValue(editor, att.EditorDataTemplateSelectorPropertyPath);
                    return(dts != null?dts.SelectTemplate(item, container) : null);
                }

                if (att.EditorDataTemplatePropertyPath != null)
                {
                    return((DataTemplate)DataBindingEvaluator.GetPropertyValue(editor, att.EditorDataTemplatePropertyPath));
                }

                var cc = editor as ContentControl;
                if (cc != null)
                {
                    if (cc.ContentTemplateSelector != null)
                    {
                        DataTemplate template = cc.ContentTemplateSelector.SelectTemplate(item, container);
                        if (template != null)
                        {
                            return(template);
                        }
                    }

                    return(cc.ContentTemplate);
                }

                var cp = editor as ContentPresenter;
                if (cp != null)
                {
                    if (cp.ContentTemplateSelector != null)
                    {
                        DataTemplate template = cp.ContentTemplateSelector.SelectTemplate(item, container);
                        if (template != null)
                        {
                            return(template);
                        }
                    }

                    return(cp.ContentTemplate);
                }
            }
            return(null);
        }
        protected virtual Window GetEditor(PropertyGridProperty property, object parameter)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            string resourceKey = string.Format("{0}", parameter);

            if (string.IsNullOrWhiteSpace(resourceKey))
            {
                var att = PropertyGridOptionsAttribute.FromProperty(property);
                if (att != null)
                {
                    resourceKey = att.EditorResourceKey;
                }

                if (string.IsNullOrWhiteSpace(resourceKey))
                {
                    resourceKey = property.DefaultEditorResourceKey;
                    if (string.IsNullOrWhiteSpace(resourceKey))
                    {
                        resourceKey = "ObjectEditorWindow";
                    }
                }
            }

            var editor = TryFindResource(resourceKey) as Window;

            if (editor != null)
            {
                editor.Owner = this.GetVisualSelfOrParent <Window>();
                if (editor.Owner != null)
                {
                    PropertyGridWindowOptions wo = PropertyGridWindowManager.GetOptions(editor);
                    if ((wo & PropertyGridWindowOptions.UseDefinedSize) == PropertyGridWindowOptions.UseDefinedSize)
                    {
                        if (double.IsNaN(editor.Left))
                        {
                            editor.Left = editor.Owner.Left + ChildEditorWindowOffset;
                        }

                        if (double.IsNaN(editor.Top))
                        {
                            editor.Top = editor.Owner.Top + ChildEditorWindowOffset;
                        }

                        if (double.IsNaN(editor.Width))
                        {
                            editor.Width = editor.Owner.Width;
                        }

                        if (double.IsNaN(editor.Height))
                        {
                            editor.Height = editor.Owner.Height;
                        }
                    }
                    else
                    {
                        editor.Left   = editor.Owner.Left + ChildEditorWindowOffset;
                        editor.Top    = editor.Owner.Top + ChildEditorWindowOffset;
                        editor.Width  = editor.Owner.Width;
                        editor.Height = editor.Owner.Height;
                    }
                }
                editor.DataContext = property;
                Selector selector = LogicalTreeHelper.FindLogicalNode(editor, "EditorSelector") as Selector;
                if (selector != null)
                {
                    selector.SelectedIndex = 0;
                }

                Grid grid = LogicalTreeHelper.FindLogicalNode(editor, "CollectionEditorListGrid") as Grid;
                if (grid != null && grid.ColumnDefinitions.Count > 2)
                {
                    if (property.IsCollection && CollectionEditorHasOnlyOneColumn(property))
                    {
                        grid.ColumnDefinitions[1].Width = new GridLength(0, GridUnitType.Pixel);
                        grid.ColumnDefinitions[2].Width = new GridLength(0, GridUnitType.Pixel);
                    }
                    else
                    {
                        grid.ColumnDefinitions[1].Width = new GridLength(5, GridUnitType.Pixel);
                        grid.ColumnDefinitions[2].Width = new GridLength(1, GridUnitType.Star);
                    }
                }

                var pge = editor as IPropertyGridEditor;
                if (pge != null)
                {
                    if (!pge.SetContext(property, parameter))
                    {
                        return(null);
                    }
                }
            }
            return(editor);
        }
Esempio n. 22
0
        public virtual bool IsAssignableFrom(Type type, Type propertyType, PropertyGridDataTemplate template, PropertyGridProperty property)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (propertyType == null)
            {
                throw new ArgumentNullException("propertyType");
            }

            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            if (type.IsAssignableFrom(propertyType))
            {
                // bool? is assignable from bool, but we don't want that match
                if (!type.IsNullable() || propertyType.IsNullable())
                {
                    return(true);
                }
            }

            // hack for nullable enums...
            if (type == PropertyGridDataTemplate.NullableEnumType)
            {
                Type enumType;
                bool nullable;
                PropertyGridProperty.IsEnumOrNullableEnum(propertyType, out enumType, out nullable);
                if (nullable)
                {
                    return(true);
                }
            }

            var options = PropertyGridOptionsAttribute.FromProperty(property);

            if (options != null)
            {
                if ((type.IsEnum || type == typeof(Enum)) && options.IsEnum)
                {
                    if (!options.IsFlagsEnum)
                    {
                        return(true);
                    }

                    if (Extensions.IsFlagsEnum(type))
                    {
                        return(true);
                    }

                    if (template.IsFlagsEnum.HasValue && template.IsFlagsEnum.Value)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Esempio n. 23
0
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }

            PropertyGridProperty property = item as PropertyGridProperty;

            if (property == null)
            {
                return(base.SelectTemplate(item, container));
            }

            DataTemplate propTemplate = PropertyGridOptionsAttribute.SelectTemplate(property, item, container);

            if (propTemplate != null)
            {
                return(propTemplate);
            }

            if (_propertyGrid == null)
            {
                _propertyGrid = container.GetVisualSelfOrParent <PropertyGrid>();
            }

            if (_propertyGrid.ValueEditorTemplateSelector != null && _propertyGrid.ValueEditorTemplateSelector != this)
            {
                DataTemplate template = _propertyGrid.ValueEditorTemplateSelector.SelectTemplate(item, container);
                if (template != null)
                {
                    return(template);
                }
            }

            foreach (PropertyGridDataTemplate template in DataTemplates)
            {
                if (Filter(template, property))
                {
                    continue;
                }

                if (template.IsCollection.HasValue && template.IsCollection.Value)
                {
                    if (string.IsNullOrWhiteSpace(template.CollectionItemPropertyType) && template.DataTemplate != null)
                    {
                        return(template.DataTemplate);
                    }

                    if (property.CollectionItemPropertyType != null)
                    {
                        foreach (Type type in template.ResolvedCollectionItemPropertyTypes)
                        {
                            if (IsAssignableFrom(type, property.CollectionItemPropertyType, template, property))
                            {
                                return(template.DataTemplate);
                            }
                        }
                    }
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(template.PropertyType) && template.DataTemplate != null)
                    {
                        return(template.DataTemplate);
                    }

                    foreach (Type type in template.ResolvedPropertyTypes)
                    {
                        if (IsAssignableFrom(type, property.PropertyType, template, property))
                        {
                            return(template.DataTemplate);
                        }
                    }
                }
            }
            return(base.SelectTemplate(item, container));
        }
 public PropertyGridEventArgs(PropertyGridProperty property)
     : this(property, null)
 {
 }
 public PropertyGridEventArgs(PropertyGridProperty property, object context)
 {
     Property = property;
     Context  = context;
 }
 public virtual PropertyGridEventArgs CreateEventArgs(PropertyGridProperty property)
 {
     return(ActivatorService.CreateInstance <PropertyGridEventArgs>(property));
 }
        public virtual IEnumerable BuildItems(PropertyGridProperty property, Type targetType, object parameter, CultureInfo culture)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            Type enumType;
            bool nullable;
            bool isEnumOrNullableEnum = PropertyGridProperty.IsEnumOrNullableEnum(property.PropertyType, out enumType, out nullable);

            PropertyGridItem zero = null;
            var att   = PropertyGridOptionsAttribute.FromProperty(property);
            var items = new ObservableCollection <PropertyGridItem>();

            if (isEnumOrNullableEnum)
            {
                if (nullable)
                {
                    PropertyGridItem item = CreateItem();
                    item.Property = property;
                    item.Name     = null; // "<unset>";
                    item.Value    = null;
                    item.IsUnset  = true;
                    items.Add(item);
                }

                string[] names  = Enum.GetNames(enumType);
                Array    values = Enum.GetValues(enumType);
                if (Extensions.IsFlagsEnum(enumType))
                {
                    ulong uvalue = EnumToUInt64(property, property.Value);

                    for (int i = 0; i < names.Length; i++)
                    {
                        string name      = names[i];
                        ulong  nameValue = EnumToUInt64(property, values.GetValue(i));
                        string displayName;
                        if (!ShowEnumField(property, enumType, names[i], out displayName))
                        {
                            continue;
                        }

                        PropertyGridItem item = CreateItem();
                        item.Property = property;
                        item.Name     = displayName;
                        item.Value    = nameValue;
                        item.IsZero   = nameValue == 0;
                        bool isChecked = true;

                        if (nameValue == 0)
                        {
                            zero = item;
                        }

                        // determine if this name is in fact a combination of other names
                        ulong bitsCount = (ulong)Extensions.GetEnumMaxPower(enumType) - 1; // skip first
                        ulong b         = 1;
                        for (ulong bit = 1; bit < bitsCount; bit++)                        // signed, skip highest bit
                        {
                            string bitName = Enum.GetName(enumType, b);
                            if (bitName != null && name != bitName && (nameValue & b) != 0)
                            {
                                if ((uvalue & b) == 0)
                                {
                                    isChecked = false;
                                }
                            }
                            b *= 2;
                        }

                        isChecked      = (uvalue & nameValue) != 0;
                        item.IsChecked = isChecked;
                        items.Add(item);
                    }

                    // determine if the lisbox is empty, which we don't want anyway
                    if (items.Count == 0)
                    {
                        PropertyGridItem item = CreateItem();
                        item.Property = property;
                        item.Name     = DefaultZeroName;
                        item.Value    = 0;
                        item.IsZero   = true;
                        items.Add(item);
                    }

                    if (uvalue == 0 && zero != null)
                    {
                        zero.IsChecked = true;
                    }
                }
                else
                {
                    for (int i = 0; i < names.Length; i++)
                    {
                        string displayName;
                        if (!ShowEnumField(property, enumType, names[i], out displayName))
                        {
                            continue;
                        }

                        PropertyGridItem item = CreateItem();
                        item.Property = property;
                        item.Name     = displayName;
                        item.Value    = values.GetValue(i);
                        item.IsZero   = i == 0; // first one is default
                        items.Add(item);
                    }
                }
            }
            else
            {
                if (att != null && att.IsEnum)
                {
                    bool manualFlags = false;
                    // either EnumList or EnumValues can be null but not both
                    // if not null, length must be the same
                    if (att.EnumNames == null || att.EnumNames.Length == 0)
                    {
                        if (att.EnumValues == null || att.EnumValues.Length == 0)
                        {
                            return(items);
                        }

                        att.EnumNames = new string[att.EnumValues.Length];
                        for (int i = 0; i < att.EnumValues.Length; i++)
                        {
                            att.EnumNames[i] = string.Format("{0}", att.EnumValues[i]);
                        }
                    }
                    else
                    {
                        if (att.EnumValues == null || att.EnumValues.Length != att.EnumNames.Length)
                        {
                            att.EnumValues = new object[att.EnumNames.Length];
                            if (att.IsFlagsEnum)
                            {
                                ulong current = 1; // don't use zero when nothing is specified in flags mode
                                manualFlags = true;
                                for (int i = 0; i < att.EnumNames.Length; i++)
                                {
                                    att.EnumValues[i] = current;
                                    current          *= 2;
                                }
                            }
                            else
                            {
                                for (int i = 0; i < att.EnumNames.Length; i++)
                                {
                                    att.EnumValues[i] = string.Format("{0}", att.EnumNames[i]);
                                }
                            }
                        }
                    }

                    // items value must of a compatible type with property.Value
                    Func <object, object> valueConverter = (v) =>
                    {
                        Type propType = property.Value != null?property.Value.GetType() : property.PropertyType;

                        if (v == null)
                        {
                            if (!propType.IsValueType)
                            {
                                return(null);
                            }

                            return(Activator.CreateInstance(propType));
                        }

                        Type vType = v.GetType();
                        if (propType.IsAssignableFrom(vType))
                        {
                            return(v);
                        }

                        return(ConversionService.ChangeType(v, propType));
                    };

                    if (att.IsFlagsEnum)
                    {
                        ulong uvalue = EnumToUInt64(property, property.Value);

                        for (int i = 0; i < att.EnumNames.Length; i++)
                        {
                            ulong nameValue = EnumToUInt64(property, att.EnumValues[i]);

                            PropertyGridItem item = CreateItem();
                            item.Property = property;
                            item.Name     = att.EnumNames[i];
                            item.Value    = valueConverter(att.EnumValues[i]);
                            if (manualFlags)
                            {
                                item.IsZero = i == 0;
                            }
                            else
                            {
                                item.IsZero = nameValue == 0;
                            }
                            bool isChecked = true;

                            if (nameValue == 0)
                            {
                                zero = item;
                            }

                            // note: in this case, we don't support names as a combination of other names
                            ulong bitsCount = (ulong)GetEnumMaxPower(att) - 1; // skip first
                            ulong b         = 1;
                            for (ulong bit = 1; bit < bitsCount; bit++)        // signed, skip highest bit
                            {
                                if ((uvalue & b) == 0)
                                {
                                    isChecked = false;
                                }
                                b *= 2;
                            }

                            isChecked      = (uvalue & nameValue) != 0;
                            item.IsChecked = isChecked;
                            items.Add(item);
                        }

                        // determine if the list is empty, which we don't want anyway
                        if (items.Count == 0)
                        {
                            PropertyGridItem item = CreateItem();
                            item.Property = property;
                            item.Name     = DefaultZeroName;
                            item.Value    = valueConverter(0);
                            item.IsZero   = true;
                            items.Add(item);
                        }

                        if (uvalue == 0 && zero != null)
                        {
                            zero.IsChecked = true;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < att.EnumNames.Length; i++)
                        {
                            PropertyGridItem item = CreateItem();
                            item.Property = property;
                            item.Name     = att.EnumNames[i];
                            item.Value    = valueConverter(att.EnumValues[i]);
                            item.IsZero   = i == 0; // first one is default
                            items.Add(item);
                        }
                    }
                }
            }

            var ctx = new Dictionary <string, object>();

            ctx["items"] = items;
            property.OnEvent(this, ActivatorService.CreateInstance <PropertyGridEventArgs>(property, ctx));
            return(items);
        }
        public static ulong EnumToUInt64(PropertyGridProperty property, object value)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            if (value == null)
            {
                return(0);
            }

            Type type = value.GetType();

            if (type.IsEnum)
            {
                return(Extensions.EnumToUInt64(value));
            }

            TypeCode typeCode = Convert.GetTypeCode(value);

            switch (typeCode)
            {
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
                return((ulong)Convert.ToInt64(value));

            case TypeCode.Byte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
                return(Convert.ToUInt64(value));
            }

            var att = PropertyGridOptionsAttribute.FromProperty(property);

            if (att == null || att.EnumNames == null)
            {
                return(0);
            }

            string svalue = string.Format("{0}", value);
            ulong  ul;

            if (ulong.TryParse(svalue, out ul))
            {
                return(ul);
            }

            var enums = ParseEnum(svalue);

            if (enums.Count == 0)
            {
                return(0);
            }

            foreach (string name in enums)
            {
                int index = IndexOf(att.EnumNames, name);
                if (index < 0)
                {
                    continue;
                }

                ulong ulvalue = Extensions.EnumToUInt64(att.EnumValues[index]);
                ul |= ulvalue;
            }
            return(ul);
        }