public PropertyGridViewModel() { PropertyViewModelFactory factory = new PropertyViewModelFactory { { typeof(char), (m, p) => new CharPropertyViewModel(m, p) }, { typeof(string), (m, p) => new StringPropertyViewModel(m, p) }, { typeof(bool), (m, p) => new BooleanPropertyViewModel(m, p) }, { typeof(float), (m, p) => new SinglePropertyViewModel(m, p) }, { typeof(double), (m, p) => new DoublePropertyViewModel(m, p) }, { typeof(decimal), (m, p) => new DecimalPropertyViewModel(m, p) }, { typeof(byte), (m, p) => new BytePropertyViewModel(m, p) }, { typeof(sbyte), (m, p) => new SBytePropertyViewModel(m, p) }, { typeof(short), (m, p) => new Int16PropertyViewModel(m, p) }, { typeof(ushort), (m, p) => new UInt16PropertyViewModel(m, p) }, { typeof(int), (m, p) => new Int32PropertyViewModel(m, p) }, { typeof(uint), (m, p) => new UInt32PropertyViewModel(m, p) }, { typeof(long), (m, p) => new Int64PropertyViewModel(m, p) }, { typeof(ulong), (m, p) => new UInt64PropertyViewModel(m, p) }, { typeof(Enum), (m, p) => new EnumPropertyViewModel(m, p) }, { typeof(Guid), (m, p) => new GuidPropertyViewModel(m, p) }, { typeof(DateTimeOffset?), (m, p) => new DateTimePropertyViewModel(m, p) }, { typeof(Vector3), (m, p) => new Vector3PropertyViewModel(m, p) }, { typeof(Vector4), (m, p) => new Vector4PropertyViewModel(m, p) }, { typeof(Quaternion), (m, p) => new QuaternionPropertyViewModel(m, p) } }; PropertyViewModelFactory.Default = factory; Messenger.Default.Register <ShowEntityPropertiesMessage>(this, m => ShowProperties(m.Entity)); }
public PropertiesViewModel() { PropertyViewModelFactory factory = new PropertyViewModelFactory { { typeof(char), (m, p) => new CharPropertyViewModel(m, p) }, { typeof(string), (m, p) => new StringPropertyViewModel(m, p) }, { typeof(bool), (m, p) => new BooleanPropertyViewModel(m, p) }, { typeof(float), (m, p) => new SinglePropertyViewModel(m, p) }, { typeof(double), (m, p) => new DoublePropertyViewModel(m, p) }, { typeof(decimal), (m, p) => new DecimalPropertyViewModel(m, p) }, { typeof(byte), (m, p) => new BytePropertyViewModel(m, p) }, { typeof(sbyte), (m, p) => new SBytePropertyViewModel(m, p) }, { typeof(short), (m, p) => new Int16PropertyViewModel(m, p) }, { typeof(ushort), (m, p) => new UInt16PropertyViewModel(m, p) }, { typeof(int), (m, p) => new Int32PropertyViewModel(m, p) }, { typeof(uint), (m, p) => new UInt32PropertyViewModel(m, p) }, { typeof(long), (m, p) => new Int64PropertyViewModel(m, p) }, { typeof(ulong), (m, p) => new UInt64PropertyViewModel(m, p) }, { typeof(Guid), (m, p) => new GuidPropertyViewModel(m, p) }, { typeof(TimeSpan), (m, p) => new TimeSpanPropertyViewModel(m, p) }, { typeof(DateTime), (m, p) => new DateTimePropertyViewModel(m, p) }, { typeof(DateTimeOffset), (m, p) => new DateTimeOffsetPropertyViewModel(m, p) }, { typeof(Vector2), (m, p) => new Vector2PropertyViewModel(m, p) }, { typeof(Vector3), (m, p) => new Vector3PropertyViewModel(m, p) }, { typeof(Vector4), (m, p) => new Vector4PropertyViewModel(m, p) }, { typeof(Quaternion), (m, p) => new QuaternionPropertyViewModel(m, p) } }; PropertyViewModelFactory.Default = factory; }
/// <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)); }