Beispiel #1
0
        /// <summary>
        ///   This method takes an object Instance and creates the property model.
        ///   The properties are organized in a hierarchy
        ///   PropertyTab
        ///   PropertyCategory
        ///   Property|OptionalProperty|WideProperty|CheckBoxProperty
        /// </summary>
        /// <param name = "instance">
        /// </param>
        /// <param name = "isEnumerable">
        /// </param>
        /// <returns>
        ///   Collection of tab ViewModels
        /// </returns>
        public virtual IList <TabViewModel> CreatePropertyModel(object instance, bool isEnumerable)
        {
            if (instance == null)
            {
                return(null);
            }

            // find the instance type
            var instanceType = isEnumerable
                                   ? TypeHelper.FindBiggestCommonType(instance as IEnumerable)
                                   : instance.GetType();

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

            // find all properties of the instance type
            var properties = isEnumerable
                                 ? TypeDescriptor.GetProperties(instanceType)
                                 : TypeDescriptor.GetProperties(instance);

            // The GetPropertyModel method does not return properties in a particular order,
            // such as alphabetical or declaration order. Your code must not depend on the
            // order in which properties are returned, because that order varies.
            TabViewModel      currentTabViewModel      = null;
            CategoryViewModel currentCategoryViewModel = null;
            Type currentComponentType = null;

            // Setting the default tab name
            // Use the type name of the Instance as the default tab name
            string tabName = DefaultTabName ?? instanceType.Name;

            // Setting the default category name
            string categoryName = DefaultCategoryName;

            propertyMap.Clear();
            int sortOrder = 0;

            var result = new List <TabViewModel>();

            foreach (PropertyDescriptor descriptor in properties)
            {
                if (descriptor == null)
                {
                    continue;
                }

                // TODO: should not show attached dependency properties?
                if (DeclaredOnly && descriptor.ComponentType != instanceType)
                {
                    continue;
                }

                if (descriptor.ComponentType != currentComponentType)
                {
                    categoryName         = DefaultCategoryName;
                    tabName              = DefaultTabName ?? descriptor.ComponentType.Name;
                    currentComponentType = descriptor.ComponentType;
                }

                // Skip properties marked with [Browsable(false)]
                if (!descriptor.IsBrowsable)
                {
                    continue;
                }

                // Read-only properties
                if (!ShowReadOnlyProperties && descriptor.IsReadOnly)
                {
                    continue;
                }

                // If RequiredAttribute is set, skip properties that don't have the given attribute
                if (RequiredAttribute != null &&
                    !AttributeHelper.ContainsAttributeOfType(descriptor.Attributes, RequiredAttribute))
                {
                    continue;
                }

                // The default value for an Enum-property is the first enum in the enumeration.
                // If the first value happens to be filtered due to the attribute [Browsable(false)],
                // the WPF-binding system ends up in an infinite loop when updating the bound value
                // due to a PropertyChanged-call. We must therefore make sure that the initially selected
                // value is one of the allowed values from the filtered enumeration.
                if (descriptor.PropertyType.BaseType == typeof(Enum))
                {
                    List <object> validEnumValues = Enum.GetValues(descriptor.PropertyType).FilterOnBrowsableAttribute();
                    // Check if the enumeration that has all values hidden before accessing the first item.
                    if (validEnumValues.Count > 0 && !validEnumValues.Contains(descriptor.GetValue(instance)))
                    {
                        descriptor.SetValue(instance, validEnumValues[0]);
                    }
                }

                // Create Property ViewModel
                var propertyViewModel = PropertyViewModelFactory.CreateViewModel(instance, descriptor);
                propertyViewModel.IsEnumerable = isEnumerable;
                propertyViewModel.SubscribeValueChanged();

                LocalizePropertyHeader(instanceType, propertyViewModel);
                propertyMap.Add(propertyViewModel.Name, propertyViewModel);
                propertyViewModel.PropertyChanged += OnPropertyChanged;

                if (propertyViewModel.SortOrder == int.MinValue)
                {
                    propertyViewModel.SortOrder = sortOrder;
                }

                sortOrder = propertyViewModel.SortOrder;

                bool categoryFound = ParseTabAndCategory(descriptor, ref tabName, ref categoryName);

                if (!categoryFound && UseDefaultCategoryNameForUncategorizedProperties)
                {
                    categoryName = DefaultCategoryName;
                    tabName      = DefaultTabName ?? descriptor.ComponentType.Name;
                }

                GetOrCreateTab(instanceType, result, tabName, sortOrder, ref currentTabViewModel,
                               ref currentCategoryViewModel);
                GetOrCreateCategory(instanceType, categoryName, sortOrder, currentTabViewModel,
                                    ref currentCategoryViewModel);

                currentCategoryViewModel.Properties.Add(propertyViewModel);
            }

            // Check that properties used as optional properties are not Browsable
            CheckOptionalProperties();

            // Sort the model using a stable sort algorithm
            return(SortPropertyModel(result));
        }
            public override void GenerateColumnDefinitions()
            {
                var list = this.ItemsSource;

                if (list == null)
                {
                    return;
                }

                var view            = CollectionViewSource.GetDefaultView(this.ItemsSource);
                var iitemProperties = view as IItemProperties;

                if (iitemProperties != null && iitemProperties.ItemProperties.Count > 0)
                {
                    foreach (var info in iitemProperties.ItemProperties)
                    {
                        var descriptor = info.Descriptor as PropertyDescriptor;
                        if (!descriptor.IsBrowsable)
                        {
                            continue;
                        }

                        Owner.ColumnDefinitions.Add(
                            new ColumnDefinition
                        {
                            Descriptor          = descriptor,
                            Header              = info.Name,
                            HorizontalAlignment = Owner.DefaultHorizontalAlignment,
                            Width = Owner.DefaultColumnWidth
                        });
                    }

                    return;
                }

                var itemType = TypeHelper.FindBiggestCommonType(list);

                var properties = TypeDescriptor.GetProperties(itemType);

                if (properties.Count == 0)
                {
                    // Otherwise try to get the property descriptors from an instance
                    properties = GetPropertiesFromInstance(list, itemType);
                }

                foreach (PropertyDescriptor descriptor in properties)
                {
                    if (!descriptor.IsBrowsable)
                    {
                        continue;
                    }

                    Owner.ColumnDefinitions.Add(
                        new ColumnDefinition
                    {
                        Descriptor          = descriptor,
                        Header              = descriptor.Name,
                        HorizontalAlignment = Owner.DefaultHorizontalAlignment,
                        Width = Owner.DefaultColumnWidth
                    });
                }

                if (Owner.ColumnDefinitions.Count == 0)
                {
                    var itemsType = TypeHelper.GetItemType(list);
                    Owner.ColumnDefinitions.Add(
                        new ColumnDefinition
                    {
                        PropertyType        = itemsType,
                        Header              = itemsType.Name,
                        HorizontalAlignment = Owner.DefaultHorizontalAlignment,
                        Width = Owner.DefaultColumnWidth
                    });
                }
            }
Beispiel #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ItemsBag"/> class.
 /// </summary>
 /// <param name="objects">
 /// The objects.
 /// </param>
 public ItemsBag(IEnumerable objects)
 {
     this.Objects     = objects;
     this.BiggestType = TypeHelper.FindBiggestCommonType(objects);
     this.Subscribe();
 }
 /// <summary>
 /// Gets the type of the items in the items source.
 /// </summary>
 /// <param name="itemsSource">The items source.</param>
 /// <returns>The type.</returns>
 protected Type GetItemType(IList itemsSource)
 {
     // iterate to find the biggest common type
     return(TypeHelper.FindBiggestCommonType(itemsSource));
 }
Beispiel #5
0
        /// <summary>
        /// Generate column definitions based on a list of items.
        /// </summary>
        /// <param name="list">The list of items.</param>
        /// <returns>A sequence of column definitions.</returns>
        /// <remarks>The constraint is that all the items in the ItemsSource's should be of the same type.
        /// For non built in type, a
        /// <code>public static T Parse(string s, IFormatProvider formatProvider)</code> and
        /// <code>public string ToString(string format, IFormatProvider formatProvider)</code> should be defined.
        /// interface type is not acceptable for no object instance can be created based on it.</remarks>
        protected override IEnumerable <ColumnDefinition> GenerateColumnDefinitions(IList list)
        {
            if (list == null)
            {
                yield break;
            }

            // Strategy 1: get properties from IItemProperties
            var view = CollectionViewSource.GetDefaultView(list);
            var itemPropertiesView = view as IItemProperties;

            if (itemPropertiesView?.ItemProperties != null && itemPropertiesView.ItemProperties.Count > 0)
            {
                foreach (var info in itemPropertiesView.ItemProperties)
                {
                    var descriptor = info.Descriptor as PropertyDescriptor;
                    if (descriptor == null || !descriptor.IsBrowsable)
                    {
                        continue;
                    }

                    var cd = new ColumnDefinition
                    {
                        PropertyName        = descriptor.Name,
                        Header              = info.Name,
                        HorizontalAlignment = this.DefaultHorizontalAlignment,
                        Width = this.DefaultColumnWidth
                    };

                    yield return(cd);
                }

                yield break;
            }

            // Strategy 2: get properties from type descriptor
            var itemType   = TypeHelper.FindBiggestCommonType(list);
            var properties = TypeDescriptor.GetProperties(itemType);

            if (properties.Count == 0)
            {
                // Otherwise try to get the property descriptors from an instance
                properties = GetPropertiesFromInstance(list, itemType);
            }

            if (properties.Count > 0)
            {
                foreach (PropertyDescriptor descriptor in properties)
                {
                    if (!descriptor.IsBrowsable)
                    {
                        continue;
                    }

                    var cd = new ColumnDefinition
                    {
                        PropertyName        = descriptor.Name,
                        Header              = descriptor.Name,
                        HorizontalAlignment = this.DefaultHorizontalAlignment,
                        Width = this.DefaultColumnWidth
                    };

                    yield return(cd);
                }

                yield break;
            }

            // Strategy 3: create a single column
            var itemsType = TypeHelper.GetItemType(list);

            yield return
                (new ColumnDefinition
            {
                Header = itemsType.Name,
                HorizontalAlignment = this.DefaultHorizontalAlignment,
                Width = this.DefaultColumnWidth
            });
        }
Beispiel #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ItemsBag" /> class.
 /// </summary>
 /// <param name="objects">The objects.</param>
 public ItemsBag(IEnumerable objects)
 {
     this.Objects     = objects as object[] ?? objects.Cast <object>().ToArray();
     this.BiggestType = TypeHelper.FindBiggestCommonType(this.Objects);
     this.Subscribe();
 }