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: 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")]
[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/DateTimeUpDown/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/NumericUpDown/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/SplitButton/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/PropertyGrid/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>

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

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

Loading…
Cancel
Save