From a4035d10e4636fb99b0441562ecee44cf91d05b8 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 28 Feb 2007 19:39:42 +0000 Subject: [PATCH] Set Canvas.Left+Canvas.Top attached properties when resizing a control inside a Canvas. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2413 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../WpfDesign/StandaloneDesigner/Window1.xaml | 4 +- .../Project/Controls/AdornerLayer.cs | 2 +- .../Controls/PropertyEditor/PropertyEditor.cs | 4 +- .../Project/DesignSurface.cs | 6 ++ .../Extensions/CanvasChildResizeSupport.cs | 64 +++++++++++++++++++ .../Extensions/DefaultChildResizeSupport.cs | 4 +- .../Extensions/PanelInstanceFactory.cs | 4 +- .../SelectedElementRectangleExtension.cs | 2 +- .../Project/{Linq.cs => Func.cs} | 15 ++++- .../Project/Services/UndoService.cs | 51 +++++++++++---- .../Project/WpfDesign.Designer.csproj | 3 +- .../Project/Xaml/XamlComponentService.cs | 2 +- .../Project/Xaml/XamlDesignItem.cs | 2 +- .../Project/Xaml/XamlModelProperty.cs | 6 ++ .../Xaml/XamlModelPropertyCollection.cs | 16 ++--- .../WpfDesign.Designer/Tests/ModelTests.cs | 49 ++++++++++++++ .../WpfDesign.XamlDom/Project/XamlObject.cs | 25 +++++++- .../WpfDesign.XamlDom/Project/XamlParser.cs | 2 +- .../WpfDesign.XamlDom/Project/XamlProperty.cs | 30 +++++++-- .../WpfDesign.XamlDom/Tests/ExampleService.cs | 39 +++++++++++ .../Tests/SimpleLoadTests.cs | 13 ++++ .../Tests/WpfDesign.XamlDom.Tests.csproj | 1 + .../WpfDesign/Project/DesignItemProperty.cs | 41 +++++++++++- .../Project/Extensions/BehaviorExtension.cs | 2 +- .../Project/Extensions/ExtensionManager.cs | 2 +- .../WpfDesign/Project/{Linq.cs => Func.cs} | 2 +- .../PropertyEditor/DesignItemDataSource.cs | 2 +- .../MultiSelectionDataSource.cs | 4 +- .../PropertyEditorBindingHelper.cs | 2 + .../WpfDesign/Project/WpfDesign.csproj | 2 +- 30 files changed, 350 insertions(+), 51 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs rename src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/{Linq.cs => Func.cs} (73%) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/ExampleService.cs rename src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/{Linq.cs => Func.cs} (98%) diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml index b0d9485d57..cc9975c62c 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml @@ -25,7 +25,9 @@ Title="WindowTitle" BorderThickness="10" Width="400" Height="300"> - + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs index a425f467df..75d46a8d14 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs @@ -64,7 +64,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls public void CopyTo(AdornerPanel[] array, int arrayIndex) { - Linq.ToArray(this).CopyTo(array, arrayIndex); + Func.ToArray(this).CopyTo(array, arrayIndex); } public bool Remove(AdornerPanel item) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs index eb30828e81..042a24bb73 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs @@ -99,7 +99,7 @@ namespace ICSharpCode.WpfDesign.Designer if (useCategories) { List categories = new List(); - foreach (IPropertyEditorDataProperty p in Linq.Sort(dataSource.Properties, ComparePropertyNames)) { + foreach (IPropertyEditorDataProperty p in Func.Sort(dataSource.Properties, ComparePropertyNames)) { if (p.Name == "Name") { continue; } @@ -117,7 +117,7 @@ namespace ICSharpCode.WpfDesign.Designer } } else { PropertyGridView grid = new PropertyGridView(); - foreach (IPropertyEditorDataProperty p in Linq.Sort(dataSource.Properties, ComparePropertyNames)) { + foreach (IPropertyEditorDataProperty p in Func.Sort(dataSource.Properties, ComparePropertyNames)) { if (p.Name == "Name") { continue; } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs index f961073478..193e0225b1 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs @@ -61,7 +61,10 @@ namespace ICSharpCode.WpfDesign.Designer void OnUndoExecuted(object sender, ExecutedRoutedEventArgs e) { + IUndoAction action = Func.First(_undoService.UndoActions); + Debug.WriteLine("Undo " + action.Title); _undoService.Undo(); + _designContext.Services.Selection.SetSelectedComponents(action.AffectedElements); } void OnUndoCanExecute(object sender, CanExecuteRoutedEventArgs e) @@ -71,7 +74,10 @@ namespace ICSharpCode.WpfDesign.Designer void OnRedoExecuted(object sender, ExecutedRoutedEventArgs e) { + IUndoAction action = Func.First(_undoService.RedoActions); + Debug.WriteLine("Redo " + action.Title); _undoService.Redo(); + _designContext.Services.Selection.SetSelectedComponents(action.AffectedElements); } void OnRedoCanExecute(object sender, CanExecuteRoutedEventArgs e) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs new file mode 100644 index 0000000000..2352b2ee97 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs @@ -0,0 +1,64 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.WpfDesign.Extensions; +using System.Windows; +using System.Windows.Controls; +using ICSharpCode.WpfDesign.Adorners; + +namespace ICSharpCode.WpfDesign.Designer.Extensions +{ + /// + /// Provides behavior for . + /// + [ExtensionFor(typeof(Canvas))] + public sealed class CanvasChildResizeSupport : BehaviorExtension, IChildResizeSupport + { + /// + protected override void OnInitialized() + { + base.OnInitialized(); + this.ExtendedItem.AddBehavior(typeof(IChildResizeSupport), this); + } + + /// + public bool CanResizeChild(DesignItem child) + { + return DefaultChildResizeSupport.Instance.CanResizeChild(child); + } + + /// + public Placement GetPlacement(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) + { + return RootElementResizeSupport.Instance.GetPlacement(child, horizontalChange, verticalChange, horizontal, vertical); + } + + /// + public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) + { + RelativePlacement p = (RelativePlacement)GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical); + DefaultChildResizeSupport.Resize(childItem, p); + + bool marginIsSet = childItem.Properties[FrameworkElement.MarginProperty].IsSet; + + DesignItemProperty left = childItem.Properties.GetAttachedProperty(Canvas.LeftProperty); + DesignItemProperty top = childItem.Properties.GetAttachedProperty(Canvas.TopProperty); + + if (left.IsSet) { + left.SetValue( p.XOffset + (double)left.ValueOnInstance); + } else if (p.XOffset != 0 && !marginIsSet) { + left.SetValue( p.XOffset ); + } + if (top.IsSet) { + top.SetValue( p.YOffset + (double)top.ValueOnInstance); + } else if (p.YOffset != 0 && !marginIsSet) { + top.SetValue( p.YOffset ); + } + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs index 5ccab5530d..77e3da4188 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs @@ -66,10 +66,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) { RelativePlacement p = (RelativePlacement)GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical); - Resize(childItem, p, horizontal, vertical); + Resize(childItem, p); } - static void Resize(DesignItem childItem, RelativePlacement p, HorizontalAlignment horizontal, VerticalAlignment vertical) + internal static void Resize(DesignItem childItem, RelativePlacement p) { DesignItemProperty margin = childItem.Properties[FrameworkElement.MarginProperty]; if (margin.IsSet) { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs index cd1d886a30..3b5037133d 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs @@ -20,7 +20,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions /// setting the Brush to null actually restores the transparent brush. /// [ExtensionFor(typeof(Panel))] - public class PanelInstanceFactory : CustomInstanceFactory + public sealed class PanelInstanceFactory : CustomInstanceFactory { Brush _transparentBrush = new SolidColorBrush(Colors.Transparent); @@ -92,7 +92,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions PropertyDescriptor property = properties[_parent._propertyName]; if (property != null) { if ((properties as System.Collections.IDictionary).IsReadOnly) { - properties = new PropertyDescriptorCollection(Linq.ToArray(properties)); + properties = new PropertyDescriptorCollection(Func.ToArray(properties)); } properties.Remove(property); properties.Add(new ShadowPropertyDescriptor(_parent, property)); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs index 81ee2776a0..2086561aa3 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs @@ -19,7 +19,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions /// Draws a dotted line around selected UIElements. /// [ExtensionFor(typeof(UIElement))] - public class SelectedElementRectangleExtension : SelectionAdornerProvider + public sealed class SelectedElementRectangleExtension : SelectionAdornerProvider { /// /// Creates a new SelectedElementRectangleExtension instance. diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs similarity index 73% rename from src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs rename to src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs index 36828f068a..d4d868ce54 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs @@ -12,7 +12,7 @@ using System.Collections.Generic; namespace ICSharpCode.WpfDesign.Designer { // Static helpers that should become extension methods in the future - static class Linq + static class Func { public static T[] ToArray(ICollection collection) { @@ -37,5 +37,18 @@ namespace ICSharpCode.WpfDesign.Designer Array.Sort(arr, comparison); return arr; } + + /// + /// Returns the first element from . + /// + public static T First(IEnumerable input) + { + if (input == null) + throw new ArgumentNullException("input"); + foreach (T item in input) { + return item; + } + throw new ArgumentException("input must not be an empty collection", "input"); + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/UndoService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/UndoService.cs index 65132ab885..3c8553e295 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/UndoService.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/UndoService.cs @@ -12,11 +12,27 @@ using System.Diagnostics; namespace ICSharpCode.WpfDesign.Designer.Services { #region ITransactionItem - interface ITransactionItem + interface ITransactionItem : IUndoAction { void Do(); void Undo(); + } + #endregion + + #region IUndoAction + /// + /// Describes an action available on the undo or redo stack. + /// + public interface IUndoAction + { + /// + /// The list of elements affected by the action. + /// + ICollection AffectedElements { get; } + /// + /// The title of the action. + /// string Title { get; } } #endregion @@ -27,6 +43,17 @@ namespace ICSharpCode.WpfDesign.Designer.Services /// sealed class UndoTransaction : ChangeGroup, ITransactionItem { + readonly ICollection affectedElements; + + internal UndoTransaction(ICollection affectedElements) + { + this.affectedElements = affectedElements; + } + + public ICollection AffectedElements { + get { return affectedElements; } + } + public enum TransactionState { Open, @@ -145,9 +172,9 @@ namespace ICSharpCode.WpfDesign.Designer.Services Stack _undoStack = new Stack(); Stack _redoStack = new Stack(); - internal UndoTransaction StartTransaction() + internal UndoTransaction StartTransaction(ICollection affectedItems) { - UndoTransaction t = new UndoTransaction(); + UndoTransaction t = new UndoTransaction(affectedItems); _transactionStack.Push(t); t.Committed += TransactionFinished; t.RolledBack += TransactionFinished; @@ -219,25 +246,27 @@ namespace ICSharpCode.WpfDesign.Designer.Services /// /// Gets the list of names of the available actions on the undo stack. /// - public IEnumerable UndoActions { + public IEnumerable UndoActions { get { - foreach (ITransactionItem item in _undoStack) { - yield return item.Title; - } + return GetActions(_undoStack); } } /// /// Gets the list of names of the available actions on the undo stack. /// - public IEnumerable RedoActions { + public IEnumerable RedoActions { get { - foreach (ITransactionItem item in _redoStack) { - yield return item.Title; - } + return GetActions(_redoStack); } } + static IEnumerable GetActions(Stack stack) + { + foreach (ITransactionItem item in stack) + yield return item; + } + /// /// Gets if there are redo actions available. /// diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index 49f3d14693..a219e5638f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -70,13 +70,14 @@ + - + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs index 53a66b5639..895301183d 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs @@ -108,7 +108,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml /// internal void UnregisterAllComponents() { - Array.ForEach(Linq.ToArray(_sites.Values), UnregisterComponentFromDesigner); + Array.ForEach(Func.ToArray(_sites.Values), UnregisterComponentFromDesigner); _sites.Clear(); } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs index bc3269117e..75f9386ac6 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs @@ -96,7 +96,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml UndoService undoService = this.Services.GetService(); if (undoService == null) throw new ServiceRequiredException(typeof(UndoService)); - UndoTransaction g = undoService.StartTransaction(); + UndoTransaction g = undoService.StartTransaction(new DesignItem[] { this }); g.Title = changeGroupTitle; return g; } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs index e4506eccd0..6ae6fdbbdb 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs @@ -248,6 +248,12 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml else property.ResetInternal(); } + + public System.Collections.Generic.ICollection AffectedElements { + get { + return new DesignItem[] { property._designItem }; + } + } } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs index 95f8a27fff..80dcf2d623 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs @@ -20,17 +20,15 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml this._item = item; } - public override DesignItemProperty this[DependencyProperty dependencyProperty] { - get { - //return new XamlModelProperty(_item, dependencyProperty); - return this[dependencyProperty.Name]; - } + + public override DesignItemProperty GetProperty(string name) + { + return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name)); } - public override DesignItemProperty this[string name] { - get { - return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name)); - } + public override DesignItemProperty GetAttachedProperty(Type ownerType, string name) + { + return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateAttachedProperty(ownerType, name)); } public override System.Collections.Generic.IEnumerator GetEnumerator() diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs index 35df388e25..dd289e8778 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs @@ -12,6 +12,7 @@ using System.Xml; using System.Diagnostics; using NUnit.Framework; using ICSharpCode.WpfDesign.Designer.Xaml; +using ICSharpCode.WpfDesign.Designer.Services; namespace ICSharpCode.WpfDesign.Designer.Tests { @@ -26,5 +27,53 @@ namespace ICSharpCode.WpfDesign.Designer.Tests AssertCanvasDesignerOutput(@"