diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs index 073675a8..f0b93b4b 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml.cs @@ -39,6 +39,16 @@ namespace Samples.Modules.PropertyGrid.Views } } + private List _valueTypes = new List() { 1, 2, 3 }; + public List ValueTypes + { + get { return _valueTypes; } + set + { + _valueTypes = value; + } + } + private string _name; public string Name { @@ -69,6 +79,17 @@ namespace Samples.Modules.PropertyGrid.Views } } + private Color _color; + public Color Color + { + get { return _color; } + set + { + _color = value; + } + } + + public Data() { Pages.Add(new Person() { FirstName = "One" }); diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Samples/App.xaml.cs b/ExtendedWPFToolkitSolution/Src/Samples/Samples/App.xaml.cs index 43df21d2..d59478b5 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Samples/App.xaml.cs +++ b/ExtendedWPFToolkitSolution/Src/Samples/Samples/App.xaml.cs @@ -18,9 +18,9 @@ namespace Samples { // Put the following code before InitializeComponent() // Sets the culture to French (France) - Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK"); + //Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK"); // Sets the UI culture to French (France) - Thread.CurrentThread.CurrentUICulture = new CultureInfo("da-DK"); + //Thread.CurrentThread.CurrentUICulture = new CultureInfo("da-DK"); base.OnStartup(e); Bootstrapper bootstrapper = new Bootstrapper(); diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Images/Delete16.png b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Images/Delete16.png new file mode 100644 index 00000000..dee2496a Binary files /dev/null and b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Images/Delete16.png differ diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditorDialog.xaml.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditor.cs similarity index 51% rename from ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditorDialog.xaml.cs rename to ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditor.cs index 594ad50b..a652b7d8 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditorDialog.xaml.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditor.cs @@ -1,72 +1,75 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; -using System.Collections; using System.Collections.ObjectModel; +using System.Collections; using System.Reflection; -using System.ComponentModel; -namespace Microsoft.Windows.Controls.PropertyGrid.Editors +namespace Microsoft.Windows.Controls { - /// - /// Interaction logic for CollectionEditorDialog.xaml - /// - public partial class CollectionEditorDialog : Window + public class CollectionEditor : Control { #region Properties - public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection), typeof(CollectionEditorDialog), new UIPropertyMetadata(null)); + public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection), typeof(CollectionEditor), new UIPropertyMetadata(null)); public ObservableCollection Items { get { return (ObservableCollection)GetValue(ItemsProperty); } set { SetValue(ItemsProperty, value); } } - public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(CollectionEditorDialog), new UIPropertyMetadata(null, OnItemsSourceChanged)); - public IEnumerable ItemsSource + public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(CollectionEditor), new UIPropertyMetadata(null, OnItemsSourceChanged)); + public IList ItemsSource { - get { return (IEnumerable)GetValue(ItemsSourceProperty); } + get { return (IList)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - CollectionEditorDialog collectionEditor = (CollectionEditorDialog)d; + CollectionEditor collectionEditor = (CollectionEditor)d; if (collectionEditor != null) - collectionEditor.OnItemSourceChanged((IEnumerable)e.OldValue, (IEnumerable)e.NewValue); + collectionEditor.OnItemSourceChanged((IList)e.OldValue, (IList)e.NewValue); } - public void OnItemSourceChanged(IEnumerable oldValue, IEnumerable newValue) + public void OnItemSourceChanged(IList oldValue, IList newValue) { if (newValue != null) { - Items = new ObservableCollection(); foreach (var item in newValue) - { - object clone = Activator.CreateInstance(item.GetType()); - CopyValues(item, clone); - Items.Add(clone); - } + Items.Add(CreateClone(item)); } } - public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register("NewItemTypes", typeof(IList), typeof(CollectionEditorDialog), new UIPropertyMetadata(null)); + public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(Type), typeof(CollectionEditor), new UIPropertyMetadata(null, new PropertyChangedCallback(ItemsSourceTypeChanged))); + public Type ItemsSourceType + { + get { return (Type)GetValue(ItemsSourceTypeProperty); } + set { SetValue(ItemsSourceTypeProperty, value); } + } + + private static void ItemsSourceTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + CollectionEditor collectionEditor = (CollectionEditor)d; + if (collectionEditor != null) + collectionEditor.ItemsSourceTypeChanged((Type)e.OldValue, (Type)e.NewValue); + } + + protected virtual void ItemsSourceTypeChanged(Type oldValue, Type newValue) + { + NewItemTypes = GetNewItemTypes(newValue); + } + + public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register("NewItemTypes", typeof(IList), typeof(CollectionEditor), new UIPropertyMetadata(null)); public IList NewItemTypes { get { return (IList)GetValue(NewItemTypesProperty); } set { SetValue(NewItemTypesProperty, value); } } - public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(CollectionEditorDialog), new UIPropertyMetadata(null)); + public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(CollectionEditor), new UIPropertyMetadata(null)); public object SelectedItem { get { return (object)GetValue(SelectedItemProperty); } @@ -77,61 +80,27 @@ namespace Microsoft.Windows.Controls.PropertyGrid.Editors #region Constructors - private CollectionEditorDialog() + static CollectionEditor() { - InitializeComponent(); - DataContext = this; + DefaultStyleKeyProperty.OverrideMetadata(typeof(CollectionEditor), new FrameworkPropertyMetadata(typeof(CollectionEditor))); } - public CollectionEditorDialog(Type type) - : this() + public CollectionEditor() { - NewItemTypes = GetNewItemTypes(type); + Items = new ObservableCollection(); + CommandBindings.Add(new CommandBinding(ApplicationCommands.New, AddNew, CanAddNew)); + CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, Delete, CanDelete)); + CommandBindings.Add(new CommandBinding(ComponentCommands.MoveDown, MoveDown, CanMoveDown)); + CommandBindings.Add(new CommandBinding(ComponentCommands.MoveUp, MoveUp, CanMoveUp)); } #endregion //Constructors - private void OkButton_Click(object sender, RoutedEventArgs e) - { - PersistChanges(); - Close(); - } - - private static void CopyValues(object source, object destination) - { - FieldInfo[] myObjectFields = source.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); - foreach (FieldInfo fi in myObjectFields) - { - fi.SetValue(destination, fi.GetValue(source)); - } - } - - private static List GetNewItemTypes(Type type) - { - List types = new List(); - var newItemTypes = type.GetGenericArguments(); - foreach (var t in newItemTypes) - { - types.Add(t); - } - return types; - } - - private void PersistChanges() - { - if (ItemsSource is IList) - { - IList list = (IList)ItemsSource; - //Need to copy all changes into ItemsSource - } - } - #region Commands private void AddNew(object sender, ExecutedRoutedEventArgs e) { - Type t = (Type)e.Parameter; - var newItem = Activator.CreateInstance(t); + var newItem = CreateNewItem((Type)e.Parameter); Items.Add(newItem); SelectedItem = newItem; } @@ -139,7 +108,7 @@ namespace Microsoft.Windows.Controls.PropertyGrid.Editors private void CanAddNew(object sender, CanExecuteRoutedEventArgs e) { Type t = e.Parameter as Type; - if (t != null && t.IsClass) + if (t != null && t.GetConstructor(Type.EmptyTypes) != null) e.CanExecute = true; } @@ -184,5 +153,81 @@ namespace Microsoft.Windows.Controls.PropertyGrid.Editors } #endregion //Commands + + #region Methods + + private static void CopyValues(object source, object destination) + { + FieldInfo[] myObjectFields = source.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + foreach (FieldInfo fi in myObjectFields) + { + fi.SetValue(destination, fi.GetValue(source)); + } + } + + private object CreateClone(object source) + { + object clone = null; + + Type type = source.GetType(); + clone = Activator.CreateInstance(type); + CopyValues(source, clone); + + return clone; + } + + private IList CreateItemsSource() + { + IList list = null; + + if (ItemsSourceType != null) + { + ConstructorInfo constructor = ItemsSourceType.GetConstructor(Type.EmptyTypes); + list = (IList)constructor.Invoke(null); + } + + return list; + } + + private object CreateNewItem(Type type) + { + return Activator.CreateInstance(type); + } + + private static List GetNewItemTypes(Type type) + { + List types = new List(); + var newItemTypes = type.GetGenericArguments(); + foreach (var t in newItemTypes) + { + types.Add(t); + } + return types; + } + + public void PersistChanges() + { + IList list = ResolveItemsSource(); + if (list == null) + return; + + //the easiest way to persist changes to the source is to just clear the source list and then add all items to it. + list.Clear(); + + foreach (var item in Items) + { + list.Add(item); + } + } + + private IList ResolveItemsSource() + { + if (ItemsSource == null) + ItemsSource = CreateItemsSource(); + + return ItemsSource; + } + + #endregion //Methods } -} +} \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditorDialog.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditorDialog.xaml new file mode 100644 index 00000000..86cb7858 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditorDialog.xaml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditorDialog.xaml.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditorDialog.xaml.cs new file mode 100644 index 00000000..1053efc3 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/CollectionEditorDialog.xaml.cs @@ -0,0 +1,55 @@ +using System; +using System.Windows; +using System.Collections; + +namespace Microsoft.Windows.Controls +{ + /// + /// Interaction logic for CollectionEditorDialog.xaml + /// + public partial class CollectionEditorDialog : Window + { + #region Properties + + public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(CollectionEditorDialog), new UIPropertyMetadata(null)); + public IList ItemsSource + { + get { return (IList)GetValue(ItemsSourceProperty); } + set { SetValue(ItemsSourceProperty, value); } + } + + public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(Type), typeof(CollectionEditorDialog), new UIPropertyMetadata(null)); + public Type ItemsSourceType + { + get { return (Type)GetValue(ItemsSourceTypeProperty); } + set { SetValue(ItemsSourceTypeProperty, value); } + } + + #endregion //Properties + + #region Constructors + + public CollectionEditorDialog() + { + InitializeComponent(); + } + + public CollectionEditorDialog(Type type) + : this() + { + ItemsSourceType = type; + } + + #endregion //Constructors + + #region Event Handlers + + private void OkButton_Click(object sender, RoutedEventArgs e) + { + _propertyGrid.PersistChanges(); + Close(); + } + + #endregion //Event Hanlders + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Themes/Generic.xaml new file mode 100644 index 00000000..e31d6d17 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Themes/Generic.xaml @@ -0,0 +1,90 @@ + + + + + + + + + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/ObjectTypeToNameConverter.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/ObjectTypeToNameConverter.cs new file mode 100644 index 00000000..70932391 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Converters/ObjectTypeToNameConverter.cs @@ -0,0 +1,17 @@ +using System; +using System.Windows.Data; + +namespace Microsoft.Windows.Controls.Core.Converters +{ + public class ObjectTypeToNameConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return value.GetType().Name; + } + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml index 6d39f0ea..25937372 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/CollectionEditor.xaml @@ -7,7 +7,7 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs index ed7edda7..a3aae628 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs @@ -10,7 +10,6 @@ using System.ComponentModel; using System.Windows.Input; using Microsoft.Windows.Controls.PropertyGrid.Editors; using Microsoft.Windows.Controls.PropertyGrid.Commands; -using System.Collections; namespace Microsoft.Windows.Controls.PropertyGrid { @@ -424,9 +423,18 @@ namespace Microsoft.Windows.Controls.PropertyGrid editor = new FontComboBoxEditor(); else if (propertyItem.PropertyType.IsGenericType) { - var interfaces = propertyItem.PropertyType.GetInterfaces(); - if (interfaces.Contains(typeof(IEnumerable))) - editor = new CollectionEditor(); + if (propertyItem.PropertyType.GetInterface("IList") != null) + { + bool isEditable = false; + + var t = propertyItem.PropertyType.GetGenericArguments()[0]; + if (!t.IsPrimitive && !t.Equals(typeof(String))) + isEditable = true; + + editor = new Microsoft.Windows.Controls.PropertyGrid.Editors.CollectionEditor(isEditable); + } + else + editor = new TextBlockEditor(); } else editor = new TextBoxEditor(); diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml index 621168ba..f2386976 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml @@ -10,6 +10,7 @@ + diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj index 958cf276..aff8952b 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj @@ -87,6 +87,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -123,7 +127,7 @@ MSBuild:Compile Designer - + MSBuild:Compile Designer @@ -177,6 +181,8 @@ + + @@ -231,7 +237,7 @@ CollectionEditor.xaml - + CollectionEditorDialog.xaml @@ -347,6 +353,9 @@ + + +