diff --git a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml index 719033d4..b750dd44 100644 --- a/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml +++ b/ExtendedWPFToolkitSolution/Src/Samples/Modules/Samples.Modules.PropertyGrid/Views/HomeView.xaml @@ -17,5 +17,12 @@ + + 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 f0b93b4b..c2d74791 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 @@ -24,7 +24,16 @@ namespace Samples.Modules.PropertyGrid.Views InitializeComponent(); _listBox.Items.Add(new Data() { Name = "Item One" }); _listBox.Items.Add(new Data() { Name = "Item Two" }); + //_editor.ItemsSourceType = typeof(List); + //_editor.ItemType = typeof(double); + //_editor.ItemsSource = new List() { "A", "B", "C" }; + //_editor.ItemsSource = new List() { 1.0, 2.0, 3.0 }; } + + //private void Button_Click(object sender, RoutedEventArgs e) + //{ + // MessageBox.Show(_editor.ItemsSource.Count.ToString()); + //} } public class Data @@ -88,7 +97,7 @@ namespace Samples.Modules.PropertyGrid.Views _color = value; } } - + public Data() { diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/PrimitiveTypeCollectionEditor.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/PrimitiveTypeCollectionEditor.cs new file mode 100644 index 00000000..02d40e6d --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Implementation/PrimitiveTypeCollectionEditor.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Collections; +using System.Reflection; +using System.Windows.Input; + +namespace Microsoft.Windows.Controls +{ + public class PrimitiveTypeCollectionEditor : ContentControl + { + #region Members + + TextBox _textBox; + Thumb _resizeThumb; + bool _surpressTextChanged; + bool _conversionFailed; + + #endregion //Members + + #region Properties + + #region IsOpen + + public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(PrimitiveTypeCollectionEditor), new UIPropertyMetadata(false, OnIsOpenChanged)); + public bool IsOpen + { + get { return (bool)GetValue(IsOpenProperty); } + set { SetValue(IsOpenProperty, value); } + } + + private static void OnIsOpenChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + PrimitiveTypeCollectionEditor primitiveTypeCollectionEditor = o as PrimitiveTypeCollectionEditor; + if (primitiveTypeCollectionEditor != null) + primitiveTypeCollectionEditor.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnIsOpenChanged(bool oldValue, bool newValue) + { + + } + + #endregion //IsOpen + + #region ItemsSource + + public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(PrimitiveTypeCollectionEditor), new UIPropertyMetadata(null, OnItemsSourceChanged)); + public IList ItemsSource + { + get { return (IList)GetValue(ItemsSourceProperty); } + set { SetValue(ItemsSourceProperty, value); } + } + + private static void OnItemsSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + PrimitiveTypeCollectionEditor primitiveTypeCollectionEditor = o as PrimitiveTypeCollectionEditor; + if (primitiveTypeCollectionEditor != null) + primitiveTypeCollectionEditor.OnItemsSourceChanged((IList)e.OldValue, (IList)e.NewValue); + } + + protected virtual void OnItemsSourceChanged(IList oldValue, IList newValue) + { + if (newValue == null) + return; + + if (ItemsSourceType == null) + ItemsSourceType = newValue.GetType(); + + if (ItemType == null) + ItemType = newValue.GetType().GetGenericArguments()[0]; + + if (newValue.Count > 0) + SetText(newValue); + } + + #endregion //ItemsSource + + public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(Type), typeof(PrimitiveTypeCollectionEditor), new UIPropertyMetadata(null)); + public Type ItemsSourceType + { + get { return (Type)GetValue(ItemsSourceTypeProperty); } + set { SetValue(ItemsSourceTypeProperty, value); } + } + + public static readonly DependencyProperty ItemTypeProperty = DependencyProperty.Register("ItemType", typeof(Type), typeof(PrimitiveTypeCollectionEditor), new UIPropertyMetadata(null)); + public Type ItemType + { + get { return (Type)GetValue(ItemTypeProperty); } + set { SetValue(ItemTypeProperty, value); } + } + + #region Text + + public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(PrimitiveTypeCollectionEditor), new UIPropertyMetadata(null, OnTextChanged)); + public string Text + { + get { return (string)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + + private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + PrimitiveTypeCollectionEditor primitiveTypeCollectionEditor = o as PrimitiveTypeCollectionEditor; + if (primitiveTypeCollectionEditor != null) + primitiveTypeCollectionEditor.OnTextChanged((string)e.OldValue, (string)e.NewValue); + } + + protected virtual void OnTextChanged(string oldValue, string newValue) + { + if (!_surpressTextChanged) + PersistChanges(); + } + + #endregion //Text + + #endregion //Properties + + #region Constructors + + static PrimitiveTypeCollectionEditor() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(PrimitiveTypeCollectionEditor), new FrameworkPropertyMetadata(typeof(PrimitiveTypeCollectionEditor))); + } + + public PrimitiveTypeCollectionEditor() + { + Keyboard.AddKeyDownHandler(this, OnKeyDown); + Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); + } + + #endregion //Constructors + + #region Bass Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _textBox = (TextBox)GetTemplateChild("PART_TextBox"); + + if (_resizeThumb != null) + _resizeThumb.DragDelta -= ResizeThumb_DragDelta; + + _resizeThumb = (Thumb)GetTemplateChild("PART_ResizeThumb"); + + if (_resizeThumb != null) + _resizeThumb.DragDelta += ResizeThumb_DragDelta; + + } + + void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e) + { + double yadjust = this._textBox.Height + e.VerticalChange; + double xadjust = this._textBox.Width + e.HorizontalChange; + + if ((xadjust >= 0) && (yadjust >= 0)) + { + this._textBox.Width = xadjust; + this._textBox.Height = yadjust; + } + } + + #endregion //Bass Class Overrides + + #region Event Handlers + + private void OnKeyDown(object sender, KeyEventArgs e) + { + switch (e.Key) + { + case Key.Escape: + case Key.Tab: + { + CloseEditor(); + break; + } + } + } + + private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) + { + CloseEditor(); + } + + #endregion //Event Handlers + + #region Methods + + private void CloseEditor() + { + if (IsOpen) + IsOpen = false; + ReleaseMouseCapture(); + } + + private 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(); + + IList items = ResolveItems(); + foreach (var item in items) + { + list.Add(item); + }; + + // if something went wrong during conversion we want to reload the text to show only valid entries + if (_conversionFailed) + SetText(list); + } + + private IList ResolveItems() + { + IList items = new List(); + + if (ItemType == null) + return items; + + string[] textArray = Text.Split('\n'); + + foreach (string s in textArray) + { + string valueString = s.TrimEnd('\r'); + if (!String.IsNullOrEmpty(valueString)) + { + object value = null; + try + { + value = Convert.ChangeType(valueString, ItemType); + } + catch + { + //a conversion failed + _conversionFailed = true; + } + + if (value != null) + items.Add(value); + } + } + + return items; + } + + private IList ResolveItemsSource() + { + if (ItemsSource == null) + ItemsSource = CreateItemsSource(); + + return ItemsSource; + } + + private IList CreateItemsSource() + { + IList list = null; + + if (ItemsSourceType != null) + { + ConstructorInfo constructor = ItemsSourceType.GetConstructor(Type.EmptyTypes); + list = (IList)constructor.Invoke(null); + } + + return list; + } + + private void SetText(IEnumerable collection) + { + _surpressTextChanged = true; + StringBuilder builder = new StringBuilder(); + foreach (object obj2 in collection) + { + builder.Append(obj2.ToString()); + builder.AppendLine(); + } + Text = builder.ToString().Trim(); + _surpressTextChanged = false; + } + + #endregion //Methods + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Themes/Generic.xaml index e31d6d17..c44a3f26 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/CollectionEditors/Themes/Generic.xaml @@ -2,8 +2,10 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Microsoft.Windows.Controls" xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters" + xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes" xmlns:propertyGrid="clr-namespace:Microsoft.Windows.Controls.PropertyGrid"> + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/ColorEditor.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/ColorEditor.cs index 9a3ff637..3a94a6a0 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/ColorEditor.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/ColorEditor.cs @@ -5,6 +5,10 @@ namespace Microsoft.Windows.Controls.PropertyGrid.Editors { public class ColorEditor : TypeEditor { + protected override void SetControlProperties() + { + Editor.DisplayColorAndName = true; + } protected override void SetValueDependencyProperty() { ValueProperty = ColorPicker.SelectedColorProperty; diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/PrimitiveTypeCollectionEditor.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/PrimitiveTypeCollectionEditor.cs new file mode 100644 index 00000000..60ae1d93 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/Editors/PrimitiveTypeCollectionEditor.cs @@ -0,0 +1,24 @@ +using System; + +namespace Microsoft.Windows.Controls.PropertyGrid.Editors +{ + public class PrimitiveTypeCollectionEditor : TypeEditor + { + protected override void SetControlProperties() + { + Editor.Content = "(Collection)"; + } + + protected override void SetValueDependencyProperty() + { + ValueProperty = Microsoft.Windows.Controls.PrimitiveTypeCollectionEditor.ItemsSourceProperty; + } + + public override void Attach(PropertyItem propertyItem) + { + Editor.ItemsSourceType = propertyItem.PropertyType; + Editor.ItemType = propertyItem.PropertyType.GetGenericArguments()[0]; + base.Attach(propertyItem); + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs index a3aae628..a55753f1 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/PropertyGrid/Implementation/PropertyGrid.cs @@ -275,8 +275,11 @@ namespace Microsoft.Windows.Controls.PropertyGrid //hitting enter on textbox will update value of underlying source if (this.SelectedProperty != null && e.Key == Key.Enter && e.OriginalSource is TextBox) { - BindingExpression be = ((TextBox)e.OriginalSource).GetBindingExpression(TextBox.TextProperty); - be.UpdateSource(); + if (!(e.OriginalSource as TextBox).AcceptsReturn) + { + BindingExpression be = ((TextBox)e.OriginalSource).GetBindingExpression(TextBox.TextProperty); + be.UpdateSource(); + } } } @@ -425,13 +428,11 @@ namespace Microsoft.Windows.Controls.PropertyGrid { 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); + editor = new Microsoft.Windows.Controls.PropertyGrid.Editors.CollectionEditor(); + else + editor = new Microsoft.Windows.Controls.PropertyGrid.Editors.PrimitiveTypeCollectionEditor(); } else editor = new TextBlockEditor(); diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj index aff8952b..1c85c907 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj @@ -216,6 +216,7 @@ + Code @@ -252,6 +253,7 @@ +