using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows; using System.Windows.Data; using System.Windows.Media; using Microsoft.Windows.Controls.PropertyGrid.Attributes; using Microsoft.Windows.Controls.PropertyGrid.Editors; namespace Microsoft.Windows.Controls.PropertyGrid { internal class PropertyGridUtilities { internal static T GetAttribute(PropertyDescriptor property) where T : Attribute { foreach (Attribute att in property.Attributes) { var tAtt = att as T; if (tAtt != null) return tAtt; } return null; } internal static PropertyItemCollection GetAlphabetizedProperties(List propertyItems) { PropertyItemCollection propertyCollection = new PropertyItemCollection(propertyItems); propertyCollection.SortBy("DisplayName", ListSortDirection.Ascending); return propertyCollection; } internal static PropertyItemCollection GetCategorizedProperties(List propertyItems) { PropertyItemCollection propertyCollection = new PropertyItemCollection(propertyItems); propertyCollection.GroupBy("Category"); propertyCollection.SortBy("Category", ListSortDirection.Ascending); propertyCollection.SortBy("DisplayName", ListSortDirection.Ascending); return propertyCollection; } internal static PropertyDescriptorCollection GetPropertyDescriptors(object instance) { PropertyDescriptorCollection descriptors; TypeConverter tc = TypeDescriptor.GetConverter(instance); if (tc == null || !tc.GetPropertiesSupported()) { if (instance is ICustomTypeDescriptor) descriptors = ((ICustomTypeDescriptor)instance).GetProperties(); else descriptors = TypeDescriptor.GetProperties(instance.GetType()); } else { descriptors = tc.GetProperties(instance); } return descriptors; } internal static PropertyItem CreatePropertyItem(PropertyDescriptor property, object instance, PropertyGrid grid, string bindingPath, int level) { PropertyItem item = CreatePropertyItem(property, instance, grid, bindingPath); item.Level = level; return item; } internal static PropertyItem CreatePropertyItem(PropertyDescriptor property, object instance, PropertyGrid grid, string bindingPath) { PropertyItem propertyItem = new PropertyItem(instance, property, grid, bindingPath); var binding = new Binding(bindingPath) { Source = instance, ValidatesOnExceptions = true, ValidatesOnDataErrors = true, Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay }; propertyItem.SetBinding(PropertyItem.ValueProperty, binding); propertyItem.Editor = PropertyGridUtilities.GetTypeEditor(propertyItem, grid.EditorDefinitions); return propertyItem; } internal static FrameworkElement GetTypeEditor(PropertyItem propertyItem, EditorDefinitionCollection editorDefinitions) { //first check for an attribute editor FrameworkElement editor = PropertyGridUtilities.GetAttibuteEditor(propertyItem); //now look for a custom editor based on editor definitions if (editor == null) editor = PropertyGridUtilities.GetCustomEditor(propertyItem, editorDefinitions); //guess we have to use the default editor if (editor == null) editor = PropertyGridUtilities.CreateDefaultEditor(propertyItem); return editor; } internal static FrameworkElement GetAttibuteEditor(PropertyItem propertyItem) { FrameworkElement editor = null; var itemsSourceAttribute = GetAttribute(propertyItem.PropertyDescriptor); if (itemsSourceAttribute != null) editor = new ItemsSourceAttributeEditor(itemsSourceAttribute).ResolveEditor(propertyItem); var editorAttribute = GetAttribute(propertyItem.PropertyDescriptor); if (editorAttribute != null) { Type type = Type.GetType(editorAttribute.EditorTypeName); var instance = Activator.CreateInstance(type); if (instance is ITypeEditor) editor = (instance as ITypeEditor).ResolveEditor(propertyItem); } return editor; } internal static FrameworkElement GetCustomEditor(PropertyItem propertyItem, EditorDefinitionCollection customTypeEditors) { FrameworkElement editor = null; //check for custom editor if (customTypeEditors.Count > 0) { //first check if the custom editor is type based EditorDefinition customEditor = customTypeEditors[propertyItem.PropertyType]; if (customEditor == null) { //must be property based customEditor = customTypeEditors[propertyItem.Name]; } if (customEditor != null) { if (customEditor.EditorTemplate != null) editor = customEditor.EditorTemplate.LoadContent() as FrameworkElement; } } return editor; } internal static FrameworkElement CreateDefaultEditor(PropertyItem propertyItem) { ITypeEditor editor = null; if (propertyItem.IsReadOnly) editor = new TextBlockEditor(); else if (propertyItem.PropertyType == typeof(bool) || propertyItem.PropertyType == typeof(bool?)) editor = new CheckBoxEditor(); else if (propertyItem.PropertyType == typeof(decimal) || propertyItem.PropertyType == typeof(decimal?)) editor = new DecimalUpDownEditor(); else if (propertyItem.PropertyType == typeof(double) || propertyItem.PropertyType == typeof(double?)) editor = new DoubleUpDownEditor(); else if (propertyItem.PropertyType == typeof(int) || propertyItem.PropertyType == typeof(int?)) editor = new IntegerUpDownEditor(); else if (propertyItem.PropertyType == typeof(DateTime) || propertyItem.PropertyType == typeof(DateTime?)) editor = new DateTimeUpDownEditor(); else if ((propertyItem.PropertyType == typeof(Color))) editor = new ColorEditor(); else if (propertyItem.PropertyType.IsEnum) editor = new EnumComboBoxEditor(); else if (propertyItem.PropertyType == typeof(TimeSpan)) editor = new TimeSpanEditor(); else if (propertyItem.PropertyType == typeof(FontFamily) || propertyItem.PropertyType == typeof(FontWeight) || propertyItem.PropertyType == typeof(FontStyle) || propertyItem.PropertyType == typeof(FontStretch)) editor = new FontComboBoxEditor(); else if (propertyItem.PropertyType.IsGenericType) { if (propertyItem.PropertyType.GetInterface("IList") != null) { var t = propertyItem.PropertyType.GetGenericArguments()[0]; if (!t.IsPrimitive && !t.Equals(typeof(String))) editor = new Microsoft.Windows.Controls.PropertyGrid.Editors.CollectionEditor(); else editor = new Microsoft.Windows.Controls.PropertyGrid.Editors.PrimitiveTypeCollectionEditor(); } else editor = new TextBlockEditor(); } else editor = new TextBoxEditor(); return editor.ResolveEditor(propertyItem); } } }