From 093c0485c25ea63a3b34217282ac5b6268e40989 Mon Sep 17 00:00:00 2001 From: brianlagunas_cp Date: Thu, 6 Oct 2011 20:16:26 +0000 Subject: [PATCH] PropertyGrid: Implemented support for complex properties. You can now drill down into a hierarchy of an object's properties. I an not sure if I will create my own attribute or use the following syntax. [TypeConverter(typeof(ExpandableObjectConverter))] public Person Admin { get { return _admin; } set { _admin = value; } } For now it works with the above syntax. --- .../Editors/CollectionEditor.xaml.cs | 2 +- .../Implementation/Editors/TypeEditor.cs | 2 +- .../Implementation/PropertyGrid.cs | 184 +---------- .../Implementation/PropertyGridUtilities.cs | 184 +++++++++++ .../Implementation/PropertyItem.cs | 156 +++++++++- .../PropertyGrid/Themes/Generic.xaml | 294 +++++++++++++++++- .../WPFToolkit.Extended.csproj | 1 + 7 files changed, 629 insertions(+), 194 deletions(-) create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml.cs index a853333f..6dd3407d 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml.cs @@ -22,7 +22,7 @@ namespace Microsoft.Windows.Controls.PropertyGrid.Editors CollectionEditorDialog editor = new CollectionEditorDialog(_item.PropertyType); Binding binding = new Binding("Value"); binding.Source = _item; - binding.Mode = _item.IsWriteable ? BindingMode.TwoWay : BindingMode.OneWay; + binding.Mode = _item.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay; BindingOperations.SetBinding(editor, CollectionEditorDialog.ItemsSourceProperty, binding); editor.ShowDialog(); } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/TypeEditor.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/TypeEditor.cs index b6ba781d..65dd9f1b 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/TypeEditor.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/TypeEditor.cs @@ -40,7 +40,7 @@ namespace Microsoft.Windows.Controls.PropertyGrid.Editors _binding.Source = propertyItem; _binding.ValidatesOnExceptions = true; _binding.ValidatesOnDataErrors = true; - _binding.Mode = propertyItem.IsWriteable ? BindingMode.TwoWay : BindingMode.OneWay; + _binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay; _binding.Converter = CreateValueConverter(); BindingOperations.SetBinding(Editor, ValueProperty, _binding); } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs index b0869610..0c9c38df 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs @@ -1,16 +1,13 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Media; using System.Windows.Controls.Primitives; -using System.ComponentModel; +using System.Windows.Data; using System.Windows.Input; -using Microsoft.Windows.Controls.PropertyGrid.Editors; using Microsoft.Windows.Controls.PropertyGrid.Commands; -using Microsoft.Windows.Controls.PropertyGrid.Attributes; namespace Microsoft.Windows.Controls.PropertyGrid { @@ -345,9 +342,9 @@ namespace Microsoft.Windows.Controls.PropertyGrid Filter = String.Empty; if (isCategorized) - Properties = GetCategorizedProperties(_propertyItemsCache); + Properties = PropertyGridUtilities.GetCategorizedProperties(_propertyItemsCache); else - Properties = GetAlphabetizedProperties(_propertyItemsCache); + Properties = PropertyGridUtilities.GetAlphabetizedProperties(_propertyItemsCache); } private List GetObjectProperties(object instance) @@ -358,11 +355,11 @@ namespace Microsoft.Windows.Controls.PropertyGrid try { - var descriptors = GetPropertyDescriptors(instance); + var descriptors = PropertyGridUtilities.GetPropertyDescriptors(instance); foreach (PropertyDescriptor descriptor in descriptors) { if (descriptor.IsBrowsable) - propertyItems.Add(CreatePropertyItem(descriptor, instance, this)); + propertyItems.Add(PropertyGridUtilities.CreatePropertyItem(descriptor, instance, this, descriptor.Name)); } } catch (Exception ex) @@ -373,175 +370,6 @@ namespace Microsoft.Windows.Controls.PropertyGrid return propertyItems; } - private 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; - } - - private PropertyItem CreatePropertyItem(PropertyDescriptor property, object instance, PropertyGrid grid) - { - PropertyItem propertyItem = new PropertyItem(instance, property, grid); - - var binding = new Binding(property.Name) - { - Source = instance, - ValidatesOnExceptions = true, - ValidatesOnDataErrors = true, - Mode = propertyItem.IsWriteable ? BindingMode.TwoWay : BindingMode.OneWay - }; - propertyItem.SetBinding(PropertyItem.ValueProperty, binding); - - propertyItem.Editor = GetTypeEditor(propertyItem); - - return propertyItem; - } - - private FrameworkElement GetTypeEditor(PropertyItem propertyItem) - { - //first check for an attribute editor - FrameworkElement editor = GetAttibuteEditor(propertyItem); - - //now look for a custom editor based on editor definitions - if (editor == null) - editor = GetCustomEditor(propertyItem, EditorDefinitions); - - //guess we have to use the default editor - if (editor == null) - editor = CreateDefaultEditor(propertyItem); - - return editor; - } - - private static FrameworkElement GetAttibuteEditor(PropertyItem propertyItem) - { - FrameworkElement editor = null; - - var itemsSourceAttribute = GetAttribute(propertyItem.PropertyDescriptor); - if (itemsSourceAttribute != null) - editor = new ItemsSourceEditor(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; - } - - public 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; - } - - private 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 - IEditorDefinition 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; - } - - private 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); - } - - private 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; - } - - private static PropertyItemCollection GetAlphabetizedProperties(List propertyItems) - { - PropertyItemCollection propertyCollection = new PropertyItemCollection(propertyItems); - propertyCollection.SortBy("DisplayName", ListSortDirection.Ascending); - return propertyCollection; - } - private void SetSelectedObjectNameBinding(object selectedObject) { if (selectedObject is FrameworkElement) diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs new file mode 100644 index 00000000..f42b3e01 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGridUtilities.cs @@ -0,0 +1,184 @@ +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) + { + 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 ItemsSourceEditor(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 + IEditorDefinition 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); + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs index 32549fe1..193b085c 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs @@ -7,6 +7,7 @@ using System.Windows.Data; using System.Windows.Input; using Microsoft.Windows.Controls.PropertyGrid.Commands; using System.Windows.Markup.Primitives; +using System.Collections.Generic; namespace Microsoft.Windows.Controls.PropertyGrid { @@ -21,6 +22,8 @@ namespace Microsoft.Windows.Controls.PropertyGrid #region Properties + public string BindingPath { get; private set; } + #region Category public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register("Category", typeof(string), typeof(PropertyItem), new UIPropertyMetadata(string.Empty)); @@ -32,7 +35,14 @@ namespace Microsoft.Windows.Controls.PropertyGrid #endregion //Category - public string Description { get { return PropertyDescriptor.Description; } } + #region Desription + + public string Description + { + get { return PropertyDescriptor.Description; } + } + + #endregion //Desription #region DisplayName @@ -72,13 +82,12 @@ namespace Microsoft.Windows.Controls.PropertyGrid #endregion //Editor + #region Instance + private object _instance; public object Instance { - get - { - return _instance; - } + get { return _instance; } private set { _instance = value; @@ -86,6 +95,10 @@ namespace Microsoft.Windows.Controls.PropertyGrid } } + #endregion //Instance + + #region IsDataBound + /// /// Gets if the property is data bound /// @@ -101,6 +114,10 @@ namespace Microsoft.Windows.Controls.PropertyGrid } } + #endregion //IsDataBound + + #region IsDynamicResource + public bool IsDynamicResource { get @@ -112,6 +129,47 @@ namespace Microsoft.Windows.Controls.PropertyGrid } } + #endregion //IsDynamicResource + + #region IsExpanded + + public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register("IsExpanded", typeof(bool), typeof(PropertyItem), new UIPropertyMetadata(false, OnIsExpandedChanged)); + public bool IsExpanded + { + get { return (bool)GetValue(IsExpandedProperty); } + set { SetValue(IsExpandedProperty, value); } + } + + private static void OnIsExpandedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + PropertyItem propertyItem = o as PropertyItem; + if (propertyItem != null) + propertyItem.OnIsExpandedChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnIsExpandedChanged(bool oldValue, bool newValue) + { + if (newValue && (Properties == null || Properties.Count == 0)) + { + GetChildProperties(); + } + } + + #endregion IsExpanded + + #region HasChildProperties + + public static readonly DependencyProperty HasChildPropertiesProperty = DependencyProperty.Register("HasChildProperties", typeof(bool), typeof(PropertyItem), new UIPropertyMetadata(false)); + public bool HasChildProperties + { + get { return (bool)GetValue(HasChildPropertiesProperty); } + set { SetValue(HasChildPropertiesProperty, value); } + } + + #endregion HasChildProperties + + #region HasResourceApplied + public bool HasResourceApplied { //TODO: need to find a better way to determine if a StaticResource has been applied to any property not just a style @@ -125,7 +183,16 @@ namespace Microsoft.Windows.Controls.PropertyGrid } } - public bool IsReadOnly { get { return PropertyDescriptor.IsReadOnly; } } + #endregion //HasResourceApplied + + #region IsReadOnly + + public bool IsReadOnly + { + get { return PropertyDescriptor.IsReadOnly; } + } + + #endregion //IsReadOnly #region IsSelected @@ -151,7 +218,18 @@ namespace Microsoft.Windows.Controls.PropertyGrid #endregion //IsSelected - public bool IsWriteable { get { return !IsReadOnly; } } + #region Properties + + public static readonly DependencyProperty PropertiesProperty = DependencyProperty.Register("Properties", typeof(PropertyItemCollection), typeof(PropertyItem), new UIPropertyMetadata(null)); + public PropertyItemCollection Properties + { + get { return (PropertyItemCollection)GetValue(PropertiesProperty); } + set { SetValue(PropertiesProperty, value); } + } + + #endregion //Properties + + #region PropertyDescriptor private PropertyDescriptor _propertyDescriptor; public PropertyDescriptor PropertyDescriptor @@ -170,9 +248,18 @@ namespace Microsoft.Windows.Controls.PropertyGrid } } + #endregion //PropertyDescriptor + public PropertyGrid PropertyGrid { get; private set; } - public Type PropertyType { get { return PropertyDescriptor.PropertyType; } } + #region PropertyType + + public Type PropertyType + { + get { return PropertyDescriptor.PropertyType; } + } + + #endregion //PropertyType public ICommand ResetValueCommand { get; private set; } @@ -199,6 +286,8 @@ namespace Microsoft.Windows.Controls.PropertyGrid #endregion //Value + #region ValueSource + /// /// Gets the value source. /// @@ -214,28 +303,38 @@ namespace Microsoft.Windows.Controls.PropertyGrid } } + #endregion //ValueSource + #endregion //Properties - #region Constructor + #region Constructors static PropertyItem() { DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyItem), new FrameworkPropertyMetadata(typeof(PropertyItem))); } - public PropertyItem(object instance, PropertyDescriptor property, PropertyGrid propertyGrid) + public PropertyItem(object instance, PropertyDescriptor property, PropertyGrid propertyGrid, string bindingPath) { - PropertyDescriptor = property; PropertyGrid = propertyGrid; Instance = instance; + BindingPath = bindingPath; - CommandBindings.Add(new CommandBinding(PropertyItemCommands.ResetValue, ExecuteResetValueCommand, CanExecuteResetValueCommand)); + if (!IsReadOnly) + { + TypeConverter converter = PropertyDescriptor.Converter; + if (converter is ExpandableObjectConverter && PropertyDescriptor.GetValue(Instance) != null) + { + HasChildProperties = true; + } + } + CommandBindings.Add(new CommandBinding(PropertyItemCommands.ResetValue, ExecuteResetValueCommand, CanExecuteResetValueCommand)); AddHandler(Mouse.PreviewMouseDownEvent, new MouseButtonEventHandler(PropertyItem_PreviewMouseDown), true); } - #endregion //Constructor + #endregion //Constructors #region Event Handlers @@ -269,5 +368,36 @@ namespace Microsoft.Windows.Controls.PropertyGrid } #endregion //Commands + + #region Methods + + private void GetChildProperties() + { + TypeConverter converter = PropertyDescriptor.Converter; + + PropertyDescriptorCollection descriptors = null; + + if (converter is ExpandableObjectConverter) + descriptors = PropertyDescriptor.GetChildProperties(); + + var propertyItems = new List(); + + try + { + foreach (PropertyDescriptor descriptor in descriptors) + { + if (descriptor.IsBrowsable) + propertyItems.Add(PropertyGridUtilities.CreatePropertyItem(descriptor, Instance, PropertyGrid, String.Format("{0}.{1}", BindingPath, descriptor.Name))); + } + } + catch (Exception ex) + { + //TODO: handle this some how + } + + Properties = PropertyGridUtilities.GetAlphabetizedProperties(propertyItems); + } + + #endregion //Methods } } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml index 4755e181..a566ce1f 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml @@ -253,7 +253,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +