Browse Source

initial checkin of PropertyGrid. Filter not implemented. Some editors aren't implemented. Icons missing for Category and Alphabetical lists of properties.

pull/1645/head
brianlagunas_cp 15 years ago
parent
commit
94a8e34b60
  1. 1
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Properties/AssemblyInfo.cs
  2. 45
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/CheckBoxEditorProvider.cs
  3. 67
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/EnumComboBoxEditorProvider.cs
  4. 110
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/FontComboBoxEditorProvider.cs
  5. 11
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/ITypeEditorProvider.cs
  6. 41
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/NumericUpDownEditorProvider.cs
  7. 42
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/TextBoxEditorProvider.cs
  8. 72
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyCategoryItem.cs
  9. 24
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyCollection.cs
  10. 323
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs
  11. 140
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs
  12. 202
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml
  13. 3
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml
  14. 18
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj

1
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Properties/AssemblyInfo.cs

@ -60,3 +60,4 @@ using System.Windows.Markup;
[assembly: XmlnsPrefix("http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended", "extToolkit")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended", "Microsoft.Windows.Controls")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended", "Microsoft.Windows.Controls.PropertyGrid")]

45
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/CheckBoxEditorProvider.cs

@ -0,0 +1,45 @@
using System;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows;
namespace Microsoft.Windows.Controls.PropertyGrid.Implementation.EditorProviders
{
public class CheckBoxEditorProvider : ITypeEditorProvider
{
CheckBox _checkbox;
public CheckBoxEditorProvider()
{
_checkbox = new CheckBox();
_checkbox.Margin = new Thickness(2, 0, 0, 0);
}
public void Initialize(PropertyItem propertyItem)
{
ResolveBinding(propertyItem);
}
public FrameworkElement ResolveEditor()
{
return _checkbox;
}
private void ResolveBinding(PropertyItem property)
{
var binding = new Binding(property.Name);
binding.Source = property.Instance;
binding.ValidatesOnExceptions = true;
binding.ValidatesOnDataErrors = true;
if (property.IsWriteable)
binding.Mode = BindingMode.TwoWay;
else
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(_checkbox, CheckBox.IsCheckedProperty, binding);
}
}
}

67
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/EnumComboBoxEditorProvider.cs

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Data;
using System.Reflection;
namespace Microsoft.Windows.Controls.PropertyGrid.Implementation.EditorProviders
{
public class EnumComboBoxEditorProvider : ITypeEditorProvider
{
ComboBox _comboBox;
public EnumComboBoxEditorProvider()
{
_comboBox = new ComboBox();
}
public void Initialize(PropertyItem propertyItem)
{
ResolveBinding(propertyItem);
SetItemsSource(propertyItem);
}
public FrameworkElement ResolveEditor()
{
return _comboBox;
}
private void ResolveBinding(PropertyItem property)
{
var binding = new Binding(property.Name);
binding.Source = property.Instance;
binding.ValidatesOnExceptions = true;
binding.ValidatesOnDataErrors = true;
if (property.IsWriteable)
binding.Mode = BindingMode.TwoWay;
else
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(_comboBox, ComboBox.SelectedItemProperty, binding);
}
private void SetItemsSource(PropertyItem property)
{
_comboBox.ItemsSource = GetValues(property.PropertyType);
}
public static object[] GetValues(Type enumType)
{
List<object> values = new List<object>();
var fields = from field in enumType.GetFields()
where field.IsLiteral
select field;
foreach (FieldInfo field in fields)
{
values.Add(field.GetValue(enumType));
}
return values.ToArray();
}
}
}

110
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/FontComboBoxEditorProvider.cs

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
namespace Microsoft.Windows.Controls.PropertyGrid.Implementation.EditorProviders
{
public class FontComboBoxEditorProvider : ITypeEditorProvider
{
ComboBox _comboBox;
public FontComboBoxEditorProvider()
{
_comboBox = new ComboBox();
}
public void Initialize(PropertyItem propertyItem)
{
ResolveBinding(propertyItem);
SetItemsSource(propertyItem);
}
public FrameworkElement ResolveEditor()
{
return _comboBox;
}
private void ResolveBinding(PropertyItem property)
{
var binding = new Binding(property.Name);
binding.Source = property.Instance;
binding.ValidatesOnExceptions = true;
binding.ValidatesOnDataErrors = true;
if (property.IsWriteable)
binding.Mode = BindingMode.TwoWay;
else
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(_comboBox, ComboBox.SelectedItemProperty, binding);
}
private void SetItemsSource(PropertyItem property)
{
if (property.PropertyType == typeof(FontFamily))
{
List<FontFamily> fonts = new List<FontFamily>();
fonts.Add(new FontFamily("Arial"));
fonts.Add(new FontFamily("Courier New"));
fonts.Add(new FontFamily("Times New Roman"));
fonts.Add(new FontFamily("Batang"));
fonts.Add(new FontFamily("BatangChe"));
fonts.Add(new FontFamily("DFKai-SB"));
fonts.Add(new FontFamily("Dotum"));
fonts.Add(new FontFamily("DutumChe"));
fonts.Add(new FontFamily("FangSong"));
fonts.Add(new FontFamily("GulimChe"));
fonts.Add(new FontFamily("Gungsuh"));
fonts.Add(new FontFamily("GungsuhChe"));
fonts.Add(new FontFamily("KaiTi"));
fonts.Add(new FontFamily("Malgun Gothic"));
fonts.Add(new FontFamily("Meiryo"));
fonts.Add(new FontFamily("Microsoft JhengHei"));
fonts.Add(new FontFamily("Microsoft YaHei"));
fonts.Add(new FontFamily("MingLiU"));
fonts.Add(new FontFamily("MingLiu_HKSCS"));
fonts.Add(new FontFamily("MingLiu_HKSCS-ExtB"));
fonts.Add(new FontFamily("MingLiu-ExtB"));
_comboBox.ItemsSource = fonts;
}
else if (property.PropertyType == typeof(FontWeight))
{
List<FontWeight> list = new List<FontWeight>()
{
FontWeights.Black, FontWeights.Bold, FontWeights.ExtraBlack, FontWeights.ExtraBold,
FontWeights.ExtraLight, FontWeights.Light, FontWeights.Medium, FontWeights.Normal, FontWeights.SemiBold,
FontWeights.Thin
};
_comboBox.ItemsSource = list;
}
else if (property.PropertyType == typeof(FontStyle))
{
List<FontStyle> list = new List<FontStyle>()
{
FontStyles.Italic,
FontStyles.Normal
};
_comboBox.ItemsSource = list;
}
else if (property.PropertyType == typeof(FontStretch))
{
List<FontStretch> list = new List<FontStretch>()
{
FontStretches.Condensed,
FontStretches.Expanded,
FontStretches.ExtraCondensed,
FontStretches.ExtraExpanded,
FontStretches.Normal,
FontStretches.SemiCondensed,
FontStretches.SemiExpanded,
FontStretches.UltraCondensed,
FontStretches.UltraExpanded
};
_comboBox.ItemsSource = list;
}
}
}
}

11
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/ITypeEditorProvider.cs

@ -0,0 +1,11 @@
using System;
using System.Windows;
namespace Microsoft.Windows.Controls.PropertyGrid.Implementation.EditorProviders
{
interface ITypeEditorProvider
{
void Initialize(PropertyItem propertyItem);
FrameworkElement ResolveEditor();
}
}

41
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/NumericUpDownEditorProvider.cs

@ -0,0 +1,41 @@
using System;
using System.Windows.Data;
using System.Windows;
namespace Microsoft.Windows.Controls.PropertyGrid.Implementation.EditorProviders
{
public class NumericUpDownEditorProvider : ITypeEditorProvider
{
NumericUpDown _numericUpDown;
public NumericUpDownEditorProvider()
{
_numericUpDown = new NumericUpDown();
}
public void Initialize(PropertyItem propertyItem)
{
ResolveBinding(propertyItem);
}
public FrameworkElement ResolveEditor()
{
return _numericUpDown;
}
private void ResolveBinding(PropertyItem property)
{
var binding = new Binding(property.Name);
binding.Source = property.Instance;
binding.ValidatesOnExceptions = true;
binding.ValidatesOnDataErrors = true;
if (property.IsWriteable)
binding.Mode = BindingMode.TwoWay;
else
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(_numericUpDown, NumericUpDown.ValueProperty, binding);
}
}
}

42
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/EditorProviders/TextBoxEditorProvider.cs

@ -0,0 +1,42 @@
using System;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows;
namespace Microsoft.Windows.Controls.PropertyGrid.Implementation.EditorProviders
{
public class TextBoxEditorProvider : ITypeEditorProvider
{
FrameworkElement _editor;
public TextBoxEditorProvider()
{
_editor = new TextBox();
}
public void Initialize(PropertyItem propertyItem)
{
ResolveBinding(propertyItem);
}
public FrameworkElement ResolveEditor()
{
return _editor;
}
private void ResolveBinding(PropertyItem property)
{
var binding = new Binding(property.Name);
binding.Source = property.Instance;
binding.ValidatesOnExceptions = true;
binding.ValidatesOnDataErrors = true;
if (property.IsWriteable)
binding.Mode = BindingMode.TwoWay;
else
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(_editor, TextBox.TextProperty, binding);
}
}
}

72
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyCategoryItem.cs

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows;
namespace Microsoft.Windows.Controls.PropertyGrid
{
public class PropertyCategoryItem : Control
{
public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register("Category", typeof(string), typeof(PropertyCategoryItem), new UIPropertyMetadata(String.Empty, new PropertyChangedCallback(OnCategoryChanged), new CoerceValueCallback(OnCoerceCategory)));
private static object OnCoerceCategory(DependencyObject o, object value)
{
PropertyCategoryItem propertyCategoryItem = o as PropertyCategoryItem;
if (propertyCategoryItem != null)
return propertyCategoryItem.OnCoerceCategory((string)value);
else
return value;
}
private static void OnCategoryChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyCategoryItem propertyCategoryItem = o as PropertyCategoryItem;
if (propertyCategoryItem != null)
propertyCategoryItem.OnCategoryChanged((string)e.OldValue, (string)e.NewValue);
}
protected virtual string OnCoerceCategory(string value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnCategoryChanged(string oldValue, string newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
public string Category
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (string)GetValue(CategoryProperty);
}
set
{
SetValue(CategoryProperty, value);
}
}
private List<PropertyItem> _Properties = new List<PropertyItem>();
public List<PropertyItem> Properties
{
get
{
return _Properties;
}
set
{
_Properties = value;
}
}
static PropertyCategoryItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyCategoryItem), new FrameworkPropertyMetadata(typeof(PropertyCategoryItem)));
}
}
}

24
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyCollection.cs

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Microsoft.Windows.Controls.PropertyGrid
{
public class PropertyCollection : ObservableCollection<object>
{
public PropertyCollection()
{
}
public PropertyCollection(List<object> list)
: base(list)
{
}
public PropertyCollection(IEnumerable<object> collection)
: base(collection)
{
}
}
}

323
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs

@ -0,0 +1,323 @@
using System;
using System.Collections.Generic;
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 Microsoft.Windows.Controls.PropertyGrid.Implementation.EditorProviders;
namespace Microsoft.Windows.Controls.PropertyGrid
{
public class PropertyGrid : Control
{
#region Members
private Thumb _dragThumb;
private List<PropertyItem> _propertyItemsCache;
#endregion //Members
#region Properties
#region IsCategorized
public static readonly DependencyProperty IsCategorizedProperty = DependencyProperty.Register("IsCategorized", typeof(bool), typeof(PropertyGrid), new UIPropertyMetadata(true, OnIsCategorizedChanged));
public bool IsCategorized
{
get { return (bool)GetValue(IsCategorizedProperty); }
set { SetValue(IsCategorizedProperty, value); }
}
private static void OnIsCategorizedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyGrid propertyGrid = o as PropertyGrid;
if (propertyGrid != null)
propertyGrid.OnIsCategorizedChanged((bool)e.OldValue, (bool)e.NewValue);
}
protected virtual void OnIsCategorizedChanged(bool oldValue, bool newValue)
{
LoadProperties(newValue);
}
#endregion //IsCategorized
#region NameWidth
public static readonly DependencyProperty NameWidthProperty = DependencyProperty.Register("NameWidth", typeof(double), typeof(PropertyGrid), new UIPropertyMetadata(120.0, OnNameWidthChanged));
public double NameWidth
{
get { return (double)GetValue(NameWidthProperty); }
set { SetValue(NameWidthProperty, value); }
}
private static void OnNameWidthChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyGrid propertyGrid = o as PropertyGrid;
if (propertyGrid != null)
propertyGrid.OnNameWidthChanged((double)e.OldValue, (double)e.NewValue);
}
protected virtual void OnNameWidthChanged(double oldValue, double newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //NameWidth
#region Properties
public static readonly DependencyProperty PropertiesProperty = DependencyProperty.Register("Properties", typeof(PropertyCollection), typeof(PropertyGrid), new UIPropertyMetadata(null, OnPropertiesChanged));
public PropertyCollection Properties
{
get { return (PropertyCollection)GetValue(PropertiesProperty); }
private set { SetValue(PropertiesProperty, value); }
}
private static void OnPropertiesChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyGrid propertyGrid = o as PropertyGrid;
if (propertyGrid != null)
propertyGrid.OnPropertiesChanged((PropertyCollection)e.OldValue, (PropertyCollection)e.NewValue);
}
protected virtual void OnPropertiesChanged(PropertyCollection oldValue, PropertyCollection newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //Properties
#region SelectedObject
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register("SelectedObject", typeof(object), typeof(PropertyGrid), new UIPropertyMetadata(null, OnSelectedObjectChanged));
public object SelectedObject
{
get { return (object)GetValue(SelectedObjectProperty); }
set { SetValue(SelectedObjectProperty, value); }
}
private static void OnSelectedObjectChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyGrid propertyInspector = o as PropertyGrid;
if (propertyInspector != null)
propertyInspector.OnSelectedObjectChanged((object)e.OldValue, (object)e.NewValue);
}
protected virtual void OnSelectedObjectChanged(object oldValue, object newValue)
{
SelectedObjectType = newValue.GetType();
if (newValue is FrameworkElement)
SelectedObjectName = (newValue as FrameworkElement).Name;
_propertyItemsCache = GetObjectProperties(newValue);
LoadProperties(IsCategorized);
}
#endregion //SelectedObject
#region SelectedObjectType
public static readonly DependencyProperty SelectedObjectTypeProperty = DependencyProperty.Register("SelectedObjectType", typeof(Type), typeof(PropertyGrid), new UIPropertyMetadata(null, OnSelectedObjectTypeChanged));
public Type SelectedObjectType
{
get { return (Type)GetValue(SelectedObjectTypeProperty); }
set { SetValue(SelectedObjectTypeProperty, value); }
}
private static void OnSelectedObjectTypeChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyGrid propertyGrid = o as PropertyGrid;
if (propertyGrid != null)
propertyGrid.OnSelectedObjectTypeChanged((Type)e.OldValue, (Type)e.NewValue);
}
protected virtual void OnSelectedObjectTypeChanged(Type oldValue, Type newValue)
{
SelectedObjectTypeName = newValue.Name;
}
#endregion //SelectedObjectType
#region SelectedObjectTypeName
public static readonly DependencyProperty SelectedObjectTypeNameProperty = DependencyProperty.Register("SelectedObjectTypeName", typeof(string), typeof(PropertyGrid), new UIPropertyMetadata(string.Empty, OnSelectedObjectTypeNameChanged));
public string SelectedObjectTypeName
{
get { return (string)GetValue(SelectedObjectTypeNameProperty); }
set { SetValue(SelectedObjectTypeNameProperty, value); }
}
private static void OnSelectedObjectTypeNameChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyGrid propertyGrid = o as PropertyGrid;
if (propertyGrid != null)
propertyGrid.OnSelectedObjectTypeNameChanged((string)e.OldValue, (string)e.NewValue);
}
protected virtual void OnSelectedObjectTypeNameChanged(string oldValue, string newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //SelectedObjectTypeName
#region SelectedObjectName
public static readonly DependencyProperty SelectedObjectNameProperty = DependencyProperty.Register("SelectedObjectName", typeof(string), typeof(PropertyGrid), new UIPropertyMetadata(string.Empty, OnSelectedObjectNameChanged));
public string SelectedObjectName
{
get { return (string)GetValue(SelectedObjectNameProperty); }
set { SetValue(SelectedObjectNameProperty, value); }
}
private static void OnSelectedObjectNameChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyGrid propertyGrid = o as PropertyGrid;
if (propertyGrid != null)
propertyGrid.OnSelectedObjectNameChanged((string)e.OldValue, (string)e.NewValue);
}
protected virtual void OnSelectedObjectNameChanged(string oldValue, string newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //SelectedObjectName
#endregion //Properties
#region Constructors
static PropertyGrid()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyGrid), new FrameworkPropertyMetadata(typeof(PropertyGrid)));
}
#endregion //Constructors
#region Base Class Overrides
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_dragThumb = (Thumb)GetTemplateChild("PART_DragThumb");
_dragThumb.DragDelta += DragThumb_DragDelta;
}
#endregion //Base Class Overrides
#region Event Handlers
void DragThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
NameWidth = Math.Max(0, NameWidth + e.HorizontalChange);
}
#endregion //Event Handlers
#region Methods
private void LoadProperties(bool isCategorized)
{
if (isCategorized)
Properties = GetCategorizedProperties(_propertyItemsCache);
else
Properties = GetAlphabetizedProperties(_propertyItemsCache);
}
private static List<PropertyItem> GetObjectProperties(object instance)
{
var propertyItems = new List<PropertyItem>();
if (instance == null)
return propertyItems;
var properties = TypeDescriptor.GetProperties(instance.GetType(), new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.All) });
// Get all properties of the type
propertyItems.AddRange(properties.Cast<PropertyDescriptor>().
Where(p => p.IsBrowsable && p.Name != "GenericParameterAttributes").
Select(property => CreatePropertyItem(property, instance)));
return propertyItems;
}
private static PropertyItem CreatePropertyItem(PropertyDescriptor property, object instance)
{
PropertyItem propertyItem = new PropertyItem(instance, property);
ITypeEditorProvider editorProvider = null;
if (propertyItem.PropertyType == typeof(string))
editorProvider = new TextBoxEditorProvider();
else if (propertyItem.PropertyType == typeof(bool))
editorProvider = new CheckBoxEditorProvider();
else if (propertyItem.PropertyType.IsEnum)
editorProvider = new EnumComboBoxEditorProvider();
else if (propertyItem.PropertyType == typeof(FontFamily) || propertyItem.PropertyType == typeof(FontWeight) || propertyItem.PropertyType == typeof(FontStyle) || propertyItem.PropertyType == typeof(FontStretch))
editorProvider = new FontComboBoxEditorProvider();
else if (propertyItem.PropertyType == typeof(double))
editorProvider = new TextBoxEditorProvider();
else if (propertyItem.PropertyType == typeof(object) || propertyItem.PropertyType == typeof(Thickness))
editorProvider = new TextBoxEditorProvider();
if (editorProvider != null)
{
editorProvider.Initialize(propertyItem);
propertyItem.Editor = editorProvider.ResolveEditor();
}
return propertyItem;
}
private PropertyCollection GetCategorizedProperties(List<PropertyItem> propertyItems)
{
PropertyCollection propertyCollection = new PropertyCollection();
CollectionViewSource src = new CollectionViewSource();
src.Source = propertyItems;
src.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
src.SortDescriptions.Add(new SortDescription("Category", ListSortDirection.Ascending));
src.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
foreach (CollectionViewGroup item in src.View.Groups)
{
PropertyCategoryItem propertyCategoryItem = new PropertyCategoryItem();
propertyCategoryItem.Category = item.Name.ToString();
foreach (var propertyitem in item.Items)
{
propertyCategoryItem.Properties.Add((PropertyItem)propertyitem);
}
propertyCollection.Add(propertyCategoryItem);
}
return propertyCollection;
}
private PropertyCollection GetAlphabetizedProperties(List<PropertyItem> propertyItems)
{
PropertyCollection propertyCollection = new PropertyCollection();
if (propertyItems == null)
return propertyCollection;
CollectionViewSource src = new CollectionViewSource();
src.Source = propertyItems;
src.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
foreach (var item in ((ListCollectionView)(src.View)))
{
propertyCollection.Add((PropertyItem)item);
}
return propertyCollection;
}
#endregion //Methods
}
}

140
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyItem.cs

@ -0,0 +1,140 @@
using System;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows;
namespace Microsoft.Windows.Controls.PropertyGrid
{
public class PropertyItem : Control
{
#region Members
public object Instance { get; private set; }
public PropertyDescriptor PropertyDescriptor { get; private set; }
#endregion //Members
#region Properties
public string Description
{
get { return PropertyDescriptor.Description; }
}
public bool IsWriteable
{
get { return !IsReadOnly; }
}
public bool IsReadOnly
{
get { return PropertyDescriptor.IsReadOnly; }
}
public Type PropertyType
{
get { return PropertyDescriptor.PropertyType; }
}
//public string Category
//{
// get { return PropertyDescriptor.Category; }
//}
public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register("Category", typeof(string), typeof(PropertyItem), new UIPropertyMetadata(string.Empty, new PropertyChangedCallback(OnCategoryChanged), new CoerceValueCallback(OnCoerceCategory)));
private static object OnCoerceCategory(DependencyObject o, object value)
{
PropertyItem propertyItem = o as PropertyItem;
if (propertyItem != null)
return propertyItem.OnCoerceCategory((string)value);
else
return value;
}
private static void OnCategoryChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertyItem propertyItem = o as PropertyItem;
if (propertyItem != null)
propertyItem.OnCategoryChanged((string)e.OldValue, (string)e.NewValue);
}
protected virtual string OnCoerceCategory(string value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnCategoryChanged(string oldValue, string newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
public string Category
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (string)GetValue(CategoryProperty);
}
set
{
SetValue(CategoryProperty, value);
}
}
#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)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //Editor
#endregion //Properties
#region Constructor
static PropertyItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyItem), new FrameworkPropertyMetadata(typeof(PropertyItem)));
}
public PropertyItem(object instance, PropertyDescriptor property)
{
Instance = instance;
PropertyDescriptor = property;
Name = PropertyDescriptor.Name;
Category = PropertyDescriptor.Category;
}
#endregion //Constructor
#region INotifyPropertyChanged Members
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
#endregion
}
}

202
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Themes/Generic.xaml

@ -0,0 +1,202 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Microsoft.Windows.Controls.PropertyGrid"
xmlns:converters="clr-namespace:Microsoft.Windows.Controls.Core.Converters">
<!-- =============================================================================== -->
<!-- PropertyGrid -->
<!-- =============================================================================== -->
<converters:InverseBoolConverter x:Key="InverseBoolConverter" />
<SolidColorBrush x:Key="GlyphBrush" Color="#FF31347C"/>
<ControlTemplate x:Key="ExpanderToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Rectangle Margin="0,0,0,0" x:Name="Rectangle" Fill="Transparent" />
<Path HorizontalAlignment="Center" x:Name="Up_Arrow" VerticalAlignment="Center" Fill="{StaticResource GlyphBrush}" Data="M 0 0 L 4 4 L 8 0 Z" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="-90" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path Visibility="Collapsed" HorizontalAlignment="Center" x:Name="Down_Arrow" VerticalAlignment="Center" Fill="{StaticResource GlyphBrush}" Data="M 0 4 L 4 0 L 8 4 Z" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="135" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" Value="Visible" TargetName="Down_Arrow" />
<Setter Property="Visibility" Value="Collapsed" TargetName="Up_Arrow" />
<Setter Property="OpacityMask" TargetName="Down_Arrow" Value="#FF000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
<Setter Property="Padding" Value="0" />
<Setter Property="Background" Value="#FFF0F0F0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" x:Name="ContentRow" />
</Grid.RowDefinitions>
<Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="#FFF0F0F0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ToggleButton Template="{StaticResource ExpanderToggleButton}" IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" OverridesDefaultStyle="True" />
<ContentPresenter Grid.Column="1" Margin="1" RecognizesAccessKey="True" ContentSource="Header" TextElement.FontWeight="Bold" />
</Grid>
</Border>
<Border Visibility="Collapsed" Grid.Row="1" x:Name="ExpandSite" Background="#FFF0F0F0" Padding="10 0 0 0">
<Border Background="#FFFFFF" BorderThickness="0" Margin="0" Padding="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Focusable="false" />
</Border>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="ExpandSite" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:PropertyCategoryItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:PropertyCategoryItem}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Expander Header="{TemplateBinding Category}" Style="{StaticResource ExpanderStyle}" IsExpanded="True">
<ItemsControl ItemsSource="{Binding Properties, RelativeSource={RelativeSource TemplatedParent}}" />
</Expander>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:PropertyItem}">
<Setter Property="BorderBrush" Value="#FFF0F0F0" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:PropertyItem}">
<Border>
<Grid VerticalAlignment="Center" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NameWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PropertyGrid}}}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border BorderThickness="0.5" BorderBrush="#FFF0F0F0" x:Name="PART_Name">
<TextBlock Text="{Binding Name, RelativeSource={RelativeSource TemplatedParent}}" Margin="7,2,0,2"/>
</Border>
<Border BorderThickness="0.5" BorderBrush="#FFF0F0F0" x:Name="PART_Editor" Grid.Column="1" Background="Transparent">
<ContentControl Content="{TemplateBinding Editor}" VerticalAlignment="Center" />
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:PropertyGrid}">
<Setter Property="Background" Value="#CED4DF" />
<Setter Property="BorderBrush" Value="#43577B" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:PropertyGrid}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="5" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="6,2,0,4">
<TextBlock Text="{TemplateBinding SelectedObjectTypeName}" FontWeight="Bold"/>
<TextBlock Width="6">:</TextBlock>
<TextBlock Text="{TemplateBinding SelectedObjectName}" />
</StackPanel>
<Grid Grid.Row="1" Margin="4,0,4,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Background="#BCC7D8" Margin="4">
<StackPanel Orientation="Horizontal" Margin="2" >
<RadioButton IsChecked="{Binding IsCategorized, RelativeSource={RelativeSource TemplatedParent}}" VerticalAlignment="Center" />
<RadioButton IsChecked="{Binding IsCategorized, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}, Mode=OneWay}" VerticalAlignment="Center"/>
</StackPanel>
</Grid>
<TextBox Grid.Column="1" Text="Not Implemented" Margin="4" Opacity=".5" />
</Grid>
<Grid Grid.Row="2" Background="White">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Properties, RelativeSource={RelativeSource TemplatedParent}}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
<Thumb x:Name="PART_DragThumb" HorizontalAlignment="Left" Width="5" Margin="6,0,0,0" Cursor="SizeWE">
<Thumb.RenderTransform>
<TranslateTransform X="{Binding NameWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PropertyGrid}}}" />
</Thumb.RenderTransform>
<Thumb.Template>
<ControlTemplate>
<Border Background="Transparent" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Grid>
<GridSplitter Height="3" Grid.Row="3" HorizontalAlignment="Stretch" />
<StackPanel Grid.Row="4" Margin="0,0,0,5">
<TextBlock Padding="2 2 2 0" FontWeight="Bold" Text="Property Name" />
<TextBlock Padding="5 2 2 0" TextWrapping="WrapWithOverflow" Text="Property Description" />
</StackPanel>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

3
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml

@ -12,5 +12,8 @@
<ResourceDictionary Source="/WPFToolkit.Extended;component/DateTimeUpDown/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/NumericUpDown/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/SplitButton/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/PropertyGrid/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

18
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj

@ -99,6 +99,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="PropertyGrid\Themes\Generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="RichTextBoxFormatBar\RichTextBoxFormatBar.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -160,6 +164,16 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="BusyIndicator\Implementation\VisualStates.BusyIndicator.cs" />
<Compile Include="PropertyGrid\Implementation\EditorProviders\CheckBoxEditorProvider.cs" />
<Compile Include="PropertyGrid\Implementation\EditorProviders\EnumComboBoxEditorProvider.cs" />
<Compile Include="PropertyGrid\Implementation\EditorProviders\FontComboBoxEditorProvider.cs" />
<Compile Include="PropertyGrid\Implementation\EditorProviders\ITypeEditorProvider.cs" />
<Compile Include="PropertyGrid\Implementation\EditorProviders\NumericUpDownEditorProvider.cs" />
<Compile Include="PropertyGrid\Implementation\EditorProviders\TextBoxEditorProvider.cs" />
<Compile Include="PropertyGrid\Implementation\PropertyGrid.cs" />
<Compile Include="PropertyGrid\Implementation\PropertyCategoryItem.cs" />
<Compile Include="PropertyGrid\Implementation\PropertyCollection.cs" />
<Compile Include="PropertyGrid\Implementation\PropertyItem.cs" />
<Compile Include="RichTextBoxFormatBar\IRichTextBoxFormatBar.cs" />
<Compile Include="RichTextBoxFormatBar\RichTextBoxFormatBar.xaml.cs">
<DependentUpon>RichTextBoxFormatBar.xaml</DependentUpon>
@ -223,7 +237,9 @@
<Resource Include="RichTextBoxFormatBar\Images\Bullets16.png" />
<Resource Include="RichTextBoxFormatBar\Images\Numbering16.png" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="PropertyGrid\Images\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

Loading…
Cancel
Save