From 85bfc4484f66c6a55b2b4ac466ee6b3074330f44 Mon Sep 17 00:00:00 2001 From: brianlagunas_cp Date: Mon, 14 Mar 2011 21:45:45 +0000 Subject: [PATCH] PropertyGrid: Working on property options, and ValueSource icons. --- .../Core/Utilities/ContextMenuUtilities.cs | 35 ++++ .../Images/AdvancedProperties11.png | Bin 0 -> 156 bytes .../PropertyGrid/Images/Database11.png | Bin 0 -> 201 bytes .../PropertyGrid/Images/Inheritance11.png | Bin 0 -> 205 bytes .../PropertyGrid/Images/Local11.png | Bin 0 -> 142 bytes .../PropertyGrid/Images/Resource11.png | Bin 0 -> 340 bytes .../PropertyGrid/Images/Style11.png | Bin 0 -> 303 bytes .../Commands/PropertyItemCommands.cs | 17 ++ .../ValueSourceToImagePathConverter.cs | 48 ++++++ .../ValueSourceToToolTipConverter.cs | 42 +++++ .../Implementation/PropertyItem.cs | 153 +++++++++++++----- .../PropertyGrid/Themes/Generic.xaml | 51 ++++-- .../WPFToolkit.Extended.csproj | 18 +++ 13 files changed, 309 insertions(+), 55 deletions(-) create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ContextMenuUtilities.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/AdvancedProperties11.png create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Database11.png create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Inheritance11.png create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Local11.png create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Resource11.png create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Style11.png create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Commands/PropertyItemCommands.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToImagePathConverter.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToToolTipConverter.cs diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ContextMenuUtilities.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ContextMenuUtilities.cs new file mode 100644 index 00000000..7c317640 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Utilities/ContextMenuUtilities.cs @@ -0,0 +1,35 @@ +using System; +using System.Windows; + +namespace Microsoft.Windows.Controls.Core.Utilities +{ + public class ContextMenuUtilities + { + public static readonly DependencyProperty OpenOnMouseLeftButtonClickProperty = DependencyProperty.RegisterAttached("OpenOnMouseLeftButtonClick", typeof(bool), typeof(FrameworkElement), new FrameworkPropertyMetadata(false, OpenOnMouseLeftButtonClickChanged)); + public static void SetOpenOnMouseLeftButtonClick(FrameworkElement element, bool value) + { + element.SetValue(OpenOnMouseLeftButtonClickProperty, value); + } + public static bool GetOpenOnMouseLeftButtonClick(FrameworkElement element) + { + return (bool)element.GetValue(OpenOnMouseLeftButtonClickProperty); + } + + public static void OpenOnMouseLeftButtonClickChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + var control = (FrameworkElement)sender; + if ((bool)e.NewValue) + { + control.PreviewMouseLeftButtonDown += (s, args) => + { + if (control.ContextMenu != null) + { + control.ContextMenu.PlacementTarget = control; + control.ContextMenu.IsOpen = true; + } + }; + } + //TODO: remove handler when set to false + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/AdvancedProperties11.png b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/AdvancedProperties11.png new file mode 100644 index 0000000000000000000000000000000000000000..0146e93220604ee4ae29f8d85d4cfa4e43033dc0 GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhoCO|{#S9F5he4R}c>anMprD_p zi(`ny)T8G%avm_?ak=>Zf$G*nYac{uXR!9p3}H+5=vnpW-34uyR;h-WchzUiTzg(n zaD9LfL-^BP`Hd=f{`RQLB-cEaW%}}U$F{>o{FAN3<~l0(=L1b<@O1TaS?83{1OVMZ BHD&++ literal 0 HcmV?d00001 diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Database11.png b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Database11.png new file mode 100644 index 0000000000000000000000000000000000000000..0f523fbd006382eb1e25194ddb888e6c070c2c89 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhoCO|{#S9F5he4R}c>anMpkTG9 zi(`ny)Z_#OMuS5V|Ns9_k1(_T@&CL2c}W#km4%DsCH4q?H!?DEnzHeLNPhI2Kk>mW zjgA)sxb;pQJaBMB?#9pcGZy+3SpTa@w!yhMMD&=TsOO6mP4&t$3B+3v>p9r>mdKI;Vst05D}vT>t<8 literal 0 HcmV?d00001 diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Inheritance11.png b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Inheritance11.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd3b491d439df16c241d1a8891a48fb9f1e021b GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhoCO|{#S9F5he4R}c>anMpkTeH zi(`ny)U6W^ayC1NxZG!7{b8SNhq}Mm#tpnj#Du0DmD*FimCgF*?#$#O4o`zl0cO5G zhd;DGG~D3Kc42z+J^ANPQ&umKJbL&_?$_wODn;ie9l6H1{+WbwLy(ux**~H`CHWK? z9?UVG@wL(P-GK=u@y%)^8Zz@$1u0koy=sUHx3vIVCg!0I1$g APXGV_ literal 0 HcmV?d00001 diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Local11.png b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Local11.png new file mode 100644 index 0000000000000000000000000000000000000000..ec521dd495926ed922cad9a5f6955c50ef29dda3 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhoCO|{#S9F5he4R}c>anMprC`N zi(`ny)Tt9U@-i539R8$s{?&t;ucLK6Ua>Mf1{ literal 0 HcmV?d00001 diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Resource11.png b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Images/Resource11.png new file mode 100644 index 0000000000000000000000000000000000000000..7275c981cfc2d53f9c1944f92e2b7ab623c85f4d GIT binary patch literal 340 zcmV-a0jvIrP)pG21!IgR2Y?&jR_>xjGGG5IsuPWqblipF;Ymb6R2Y?=kh^LEQ4of|vpJ?PDkwpaH4l)&e#?|%wT+!%tMzui zKy0=Pqz@@Awz5>x`3Q=om%_^yDiY+#SOgarZOjh?Gs6%61@3`}#HQNr$ao$~wcU}+ zKY%(f&CjkpD2v``$!@zLmCjHp75F_EJ{o1EltP~sw)+Fa@Q7^}Bh~(R#p`n-x|N9V z*7}mg9_-@FmCf07LOuyU?{#GXc&>vn=4K{i44&%%U;+5S0Il^+vep_u7{mkC{6L1` zk!&^>5ySPL=WoxA2TUg)ah@!Cqv=%}|LXZJoB-yaf_+9%NrM0Y002ovPDHLkV1mgy Be|Z1^ literal 0 HcmV?d00001 diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Commands/PropertyItemCommands.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Commands/PropertyItemCommands.cs new file mode 100644 index 00000000..f1db5ce6 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Commands/PropertyItemCommands.cs @@ -0,0 +1,17 @@ +using System; +using System.Windows.Input; + +namespace Microsoft.Windows.Controls.PropertyGrid.Commands +{ + public static class PropertyItemCommands + { + private static RoutedCommand _resetValueCommand = new RoutedCommand(); + public static RoutedCommand ResetValue + { + get + { + return _resetValueCommand; + } + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToImagePathConverter.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToImagePathConverter.cs new file mode 100644 index 00000000..51aadbb7 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToImagePathConverter.cs @@ -0,0 +1,48 @@ +using System; +using System.Windows; +using System.Windows.Data; +using System.Windows.Media.Imaging; + +namespace Microsoft.Windows.Controls.PropertyGrid.Converters +{ + public class ValueSourceToImagePathConverter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + BaseValueSource bvs = (BaseValueSource)value; + + string uriPrefix = "/WPFToolkit.Extended;component/PropertyGrid/Images/"; + string imageName = "AdvancedProperties11"; + + switch (bvs) + { + case BaseValueSource.Inherited: + case BaseValueSource.DefaultStyle: + case BaseValueSource.ImplicitStyleReference: + imageName = "Inheritance11"; + break; + case BaseValueSource.DefaultStyleTrigger: + break; + case BaseValueSource.Style: + imageName = "Style11"; + break; + + case BaseValueSource.Local: + imageName = "Local11"; + break; + } + + + return new BitmapImage(new Uri(String.Format("{0}{1}.png", uriPrefix, imageName), UriKind.RelativeOrAbsolute)); + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToToolTipConverter.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToToolTipConverter.cs new file mode 100644 index 00000000..2b70c134 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Converters/ValueSourceToToolTipConverter.cs @@ -0,0 +1,42 @@ +using System; +using System.Windows; +using System.Windows.Data; + +namespace Microsoft.Windows.Controls.PropertyGrid.Converters +{ + class ValueSourceToToolTipConverter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + BaseValueSource bvs = (BaseValueSource)value; + string toolTip = "Advanced Properties"; + + switch (bvs) + { + case BaseValueSource.Inherited: + case BaseValueSource.DefaultStyle: + case BaseValueSource.ImplicitStyleReference: + toolTip = "Inheritance"; + break; + case BaseValueSource.Style: + toolTip = "Style Setter"; + break; + + case BaseValueSource.Local: + toolTip = "Local"; + break; + } + + return toolTip; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs index 382b10f9..fa3f2be7 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs @@ -1,8 +1,12 @@ using System; -using System.Windows.Controls; +using System.Linq; using System.ComponentModel; using System.Windows; +using System.Windows.Controls; using System.Windows.Data; +using System.Windows.Input; +using Microsoft.Windows.Controls.PropertyGrid.Commands; +using System.Windows.Markup.Primitives; namespace Microsoft.Windows.Controls.PropertyGrid { @@ -11,6 +15,7 @@ namespace Microsoft.Windows.Controls.PropertyGrid #region Members private DependencyPropertyDescriptor _dpDescriptor; + private MarkupObject _markupObject; #endregion //Members @@ -29,7 +34,30 @@ namespace Microsoft.Windows.Controls.PropertyGrid public string Description { get { return PropertyDescriptor.Description; } } - public object Instance { get; private set; } + #region Editor + + public static readonly DependencyProperty EditorProperty = DependencyProperty.Register("Editor", typeof(FrameworkElement), typeof(PropertyItem), new UIPropertyMetadata(null)); + public FrameworkElement Editor + { + get { return (FrameworkElement)GetValue(EditorProperty); } + set { SetValue(EditorProperty, value); } + } + + #endregion //Editor + + private object _instance; + public object Instance + { + get + { + return _instance; + } + private set + { + _instance = value; + _markupObject = MarkupWriter.GetMarkupObjectFor(_instance); + } + } /// /// Gets if the property is data bound @@ -46,6 +74,30 @@ namespace Microsoft.Windows.Controls.PropertyGrid } } + 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; + } + } + + 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; + } + } + public bool IsReadOnly { get { return PropertyDescriptor.IsReadOnly; } } #region IsSelected @@ -74,41 +126,37 @@ namespace Microsoft.Windows.Controls.PropertyGrid public bool IsWriteable { get { return !IsReadOnly; } } - public PropertyDescriptor PropertyDescriptor { get; private set; } + private PropertyDescriptor _propertyDescriptor; + public PropertyDescriptor PropertyDescriptor + { + get + { + return _propertyDescriptor; + } + private set + { + _propertyDescriptor = value; + Name = _propertyDescriptor.Name; + Category = _propertyDescriptor.Category; + _dpDescriptor = DependencyPropertyDescriptor.FromProperty(_propertyDescriptor); + } + } public PropertyGrid PropertyGrid { get; private set; } public Type PropertyType { get { return PropertyDescriptor.PropertyType; } } - #region Editor - - public static readonly DependencyProperty EditorProperty = DependencyProperty.Register("Editor", typeof(FrameworkElement), typeof(PropertyItem), new UIPropertyMetadata(null)); - public FrameworkElement Editor - { - get { return (FrameworkElement)GetValue(EditorProperty); } - set { SetValue(EditorProperty, value); } - } - - #endregion //Editor + public ICommand ResetValueCommand { get; private set; } #region Value - public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(PropertyItem), new UIPropertyMetadata(null, new PropertyChangedCallback(OnValueChanged), new CoerceValueCallback(OnCoerceValue))); + 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 object OnCoerceValue(DependencyObject o, object value) - { - PropertyItem propertyItem = o as PropertyItem; - if (propertyItem != null) - return propertyItem.OnCoerceValue((object)value); - else - return value; - } - private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { PropertyItem propertyItem = o as PropertyItem; @@ -116,16 +164,10 @@ namespace Microsoft.Windows.Controls.PropertyGrid propertyItem.OnValueChanged((object)e.OldValue, (object)e.NewValue); } - protected virtual object OnCoerceValue(object value) - { - // TODO: Keep the proposed value within the desired range. - return value; - } - protected virtual void OnValueChanged(object oldValue, object newValue) { // TODO: Add your property changed side-effects. Descendants can override as well. - } + } #endregion //Value @@ -155,29 +197,62 @@ namespace Microsoft.Windows.Controls.PropertyGrid public PropertyItem(object instance, PropertyDescriptor property, PropertyGrid propertyGrid) { - Instance = instance; + PropertyDescriptor = property; - Name = PropertyDescriptor.Name; - Category = PropertyDescriptor.Category; PropertyGrid = propertyGrid; + Instance = instance; - _dpDescriptor = DependencyPropertyDescriptor.FromProperty(property); + CommandBindings.Add(new CommandBinding(PropertyItemCommands.ResetValue, ExecuteResetValueCommand, CanExecuteResetValueCommand)); + + AddHandler(Mouse.MouseDownEvent, new MouseButtonEventHandler(PropertyItem_MouseDown), true); + AddHandler(Mouse.PreviewMouseDownEvent, new MouseButtonEventHandler(PropertyItem_PreviewMouseDown), true); } #endregion //Constructor - #region Base Class Overrides + #region Event Handlers - protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) + void PropertyItem_MouseDown(object sender, MouseButtonEventArgs e) { - IsSelected = true; - if (Editor != null) Editor.Focus(); e.Handled = true; } - #endregion //Base Class Overrides + void PropertyItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) + { + IsSelected = true; + + //if it is a comboBox then the selection will not take when Focus is called + if (!(e.Source is ComboBox)) + Focus(); + } + + #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 } } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml index ce62e3c5..59e7645f 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml @@ -1,13 +1,18 @@  + xmlns:converters="clr-namespace:Microsoft.Windows.Controls.Core.Converters" + xmlns:pgConverters="clr-namespace:Microsoft.Windows.Controls.PropertyGrid.Converters" + xmlns:utilities="clr-namespace:Microsoft.Windows.Controls.Core.Utilities" + xmlns:commands="clr-namespace:Microsoft.Windows.Controls.PropertyGrid.Commands"> + + @@ -213,12 +218,17 @@