public virtual PropertyGridProperty CreateProperty()
 {
     return(ActivatorService.CreateInstance <PropertyGridProperty>(this));
 }
 public virtual DynamicObject CreateDynamicObject()
 {
     return(ActivatorService.CreateInstance <DynamicObject>());
 }
        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 virtual PropertyGridItem CreateItem()
 {
     return(ActivatorService.CreateInstance <PropertyGridItem>());
 }
 public virtual PropertyGridEventArgs CreateEventArgs(PropertyGridProperty property)
 {
     return(ActivatorService.CreateInstance <PropertyGridEventArgs>(property));
 }
 public virtual PropertyGridDataProvider CreateDataProvider(object value)
 {
     return(ActivatorService.CreateInstance <PropertyGridDataProvider>(this, value));
 }