/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs
C# | 415 lines | 308 code | 97 blank | 10 comment | 41 complexity | 5ec6d52da37460c9ea13941c9059a811 MD5 | raw file
- 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.Input;
- using System.Windows.Markup.Primitives;
- using Microsoft.Windows.Controls.PropertyGrid.Commands;
- using Microsoft.Windows.Controls.PropertyGrid.Attributes;
-
- namespace Microsoft.Windows.Controls.PropertyGrid
- {
- public class PropertyItem : Control
- {
- #region Members
-
- private DependencyPropertyDescriptor _dpDescriptor;
- private MarkupObject _markupObject;
-
- #endregion //Members
-
- #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));
- public string Category
- {
- get { return (string)GetValue(CategoryProperty); }
- set { SetValue(CategoryProperty, value); }
- }
-
- #endregion //Category
-
- #region Description
-
- public string Description
- {
- get { return PropertyDescriptor.Description; }
- }
-
- #endregion //Description
-
- #region DisplayName
-
- public static readonly DependencyProperty DisplayNameProperty = DependencyProperty.Register("DisplayName", typeof(string), typeof(PropertyItem), new UIPropertyMetadata(null));
- public string DisplayName
- {
- get { return (string)GetValue(DisplayNameProperty); }
- set { SetValue(DisplayNameProperty, value); }
- }
-
- #endregion //DisplayName
-
- #region Editor
-
- public static readonly DependencyProperty EditorProperty = DependencyProperty.Register("Editor", typeof(FrameworkElement), typeof(PropertyItem), new UIPropertyMetadata(null, OnEditorChanged));
- public FrameworkElement Editor
- {
- get { return (FrameworkElement)GetValue(EditorProperty); }
- set { SetValue(EditorProperty, value); }
- }
-
- private static void OnEditorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
- {
- PropertyItem propertyItem = o as PropertyItem;
- if (propertyItem != null)
- propertyItem.OnEditorChanged((FrameworkElement)e.OldValue, (FrameworkElement)e.NewValue);
- }
-
- protected virtual void OnEditorChanged(FrameworkElement oldValue, FrameworkElement newValue)
- {
- if (oldValue != null)
- oldValue.DataContext = null;
-
- if (newValue != null)
- newValue.DataContext = this;
- }
-
- #endregion //Editor
-
- #region Instance
-
- private object _instance;
- public object Instance
- {
- get { return _instance; }
- private set
- {
- _instance = value;
- _markupObject = MarkupWriter.GetMarkupObjectFor(_instance);
- }
- }
-
- #endregion //Instance
-
- #region IsDataBound
-
- /// <summary>
- /// Gets if the property is data bound
- /// </summary>
- public bool IsDataBound
- {
- get
- {
- var dependencyObject = Instance as DependencyObject;
- if (dependencyObject != null && _dpDescriptor != null)
- return BindingOperations.GetBindingExpressionBase(dependencyObject, _dpDescriptor.DependencyProperty) != null;
-
- return false;
- }
- }
-
- #endregion //IsDataBound
-
- #region IsDynamicResource
-
- public bool IsDynamicResource
- {
- get
- {
- var markupProperty = _markupObject.Properties.Where(p => p.Name == PropertyDescriptor.Name).FirstOrDefault();
- if (markupProperty != null)
- return markupProperty.Value is DynamicResourceExtension;
- return false;
- }
- }
-
- #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
- get
- {
- var markupProperty = _markupObject.Properties.Where(p => p.Name == PropertyDescriptor.Name).FirstOrDefault();
- if (markupProperty != null)
- return markupProperty.Value is Style;
-
- return false;
- }
- }
-
- #endregion //HasResourceApplied
-
- public bool IsReadOnly { get; private set; }
-
- #region IsSelected
-
- public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(PropertyItem), new UIPropertyMetadata(false, OnIsSelectedChanged));
- public bool IsSelected
- {
- get { return (bool)GetValue(IsSelectedProperty); }
- set { SetValue(IsSelectedProperty, value); }
- }
-
- private static void OnIsSelectedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
- {
- PropertyItem propertyItem = o as PropertyItem;
- if (propertyItem != null)
- propertyItem.OnIsSelectedChanged((bool)e.OldValue, (bool)e.NewValue);
- }
-
- protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue)
- {
- if (newValue)
- PropertyGrid.SelectedProperty = this;
- }
-
- #endregion //IsSelected
-
- #region Level
-
- public static readonly DependencyProperty LevelProperty = DependencyProperty.Register("Level", typeof(int), typeof(PropertyItem), new UIPropertyMetadata(0));
- public int Level
- {
- get { return (int)GetValue(LevelProperty); }
- set { SetValue(LevelProperty, value); }
- }
-
- #endregion //Level
-
- #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
- {
- get
- {
- return _propertyDescriptor;
- }
- private set
- {
- _propertyDescriptor = value;
- _dpDescriptor = DependencyPropertyDescriptor.FromProperty(_propertyDescriptor);
- }
- }
-
- #endregion //PropertyDescriptor
-
- public PropertyGrid PropertyGrid { get; private set; }
-
- #region PropertyType
-
- public Type PropertyType
- {
- get { return PropertyDescriptor.PropertyType; }
- }
-
- #endregion //PropertyType
-
- public ICommand ResetValueCommand { get; private set; }
-
- #region Value
-
- public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(PropertyItem), new UIPropertyMetadata(null, OnValueChanged));
- public object Value
- {
- get { return (object)GetValue(ValueProperty); }
- set { SetValue(ValueProperty, value); }
- }
-
- private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
- {
- PropertyItem propertyItem = o as PropertyItem;
- if (propertyItem != null)
- propertyItem.OnValueChanged((object)e.OldValue, (object)e.NewValue);
- }
-
- protected virtual void OnValueChanged(object oldValue, object newValue)
- {
- // TODO: Add your property changed side-effects. Descendants can override as well.
- }
-
- #endregion //Value
-
- #region ValueSource
-
- /// <summary>
- /// Gets the value source.
- /// </summary>
- public BaseValueSource ValueSource
- {
- get
- {
- var dependencyObject = Instance as DependencyObject;
- if (_dpDescriptor != null && dependencyObject != null)
- return DependencyPropertyHelper.GetValueSource(dependencyObject, _dpDescriptor.DependencyProperty).BaseValueSource;
-
- return BaseValueSource.Unknown;
- }
- }
-
- #endregion //ValueSource
-
- #endregion //Properties
-
- #region Constructors
-
- static PropertyItem()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyItem), new FrameworkPropertyMetadata(typeof(PropertyItem)));
- }
-
- public PropertyItem(object instance, PropertyDescriptor property, PropertyGrid propertyGrid, string bindingPath)
- {
- PropertyDescriptor = property;
- PropertyGrid = propertyGrid;
- Instance = instance;
- BindingPath = bindingPath;
-
- SetPropertyDescriptorProperties();
- ResolveExpandableObject();
-
- CommandBindings.Add(new CommandBinding(PropertyItemCommands.ResetValue, ExecuteResetValueCommand, CanExecuteResetValueCommand));
- AddHandler(Mouse.PreviewMouseDownEvent, new MouseButtonEventHandler(PropertyItem_PreviewMouseDown), true);
- }
-
- #endregion //Constructors
-
- #region Event Handlers
-
- void PropertyItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
- {
- IsSelected = true;
- }
-
- #endregion //Event Handlers
-
- #region Commands
-
- private void ExecuteResetValueCommand(object sender, ExecutedRoutedEventArgs e)
- {
- if (PropertyDescriptor.CanResetValue(Instance))
- PropertyDescriptor.ResetValue(Instance);
-
- //TODO: notify UI that the ValueSource may have changed to update the icon
- }
-
- private void CanExecuteResetValueCommand(object sender, CanExecuteRoutedEventArgs e)
- {
- bool canExecute = false;
-
- if (PropertyDescriptor.CanResetValue(Instance) && !PropertyDescriptor.IsReadOnly)
- {
- canExecute = true;
- }
-
- e.CanExecute = canExecute;
- }
-
- #endregion //Commands
-
- #region Methods
-
- private void GetChildProperties()
- {
- if (Value == null)
- return;
-
- var propertyItems = new List<PropertyItem>();
-
- try
- {
- PropertyDescriptorCollection descriptors = PropertyGridUtilities.GetPropertyDescriptors(Value);
-
- foreach (PropertyDescriptor descriptor in descriptors)
- {
- if (descriptor.IsBrowsable)
- propertyItems.Add(PropertyGridUtilities.CreatePropertyItem(descriptor, Instance, PropertyGrid, String.Format("{0}.{1}", BindingPath, descriptor.Name), Level + 1));
- }
- }
- catch (Exception ex)
- {
- //TODO: handle this some how
- }
-
- Properties = PropertyGridUtilities.GetAlphabetizedProperties(propertyItems);
- }
-
- private void ResolveExpandableObject()
- {
- var attribute = PropertyGridUtilities.GetAttribute<ExpandableObjectAttribute>(PropertyDescriptor);
- if (attribute != null)
- {
- HasChildProperties = true;
- IsReadOnly = true;
- }
- }
-
- private void SetPropertyDescriptorProperties()
- {
- Name = PropertyDescriptor.Name;
- DisplayName = PropertyDescriptor.DisplayName;
- Category = PropertyDescriptor.Category;
- IsReadOnly = PropertyDescriptor.IsReadOnly;
- }
-
- #endregion //Methods
- }
- }