From 8ce6c3c1d07568407711b7c6c88fbb6c53e9ba2c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 10 Mar 2007 19:31:05 +0000 Subject: [PATCH] Added row/column creation adorner for Grid. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2441 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../WpfDesign/StandaloneDesigner/Window1.xaml | 13 +- .../Project/Controls/ControlStyles.xaml | 67 +++++- .../Project/Controls/GridAdorner.cs | 195 ++++++++++++++++++ .../Project/Controls/WindowClone.cs | 10 +- .../Extensions/CanvasPlacementSupport.cs | 10 - .../Project/Extensions/GridAdornerProvider.cs | 130 ++++++++++++ .../Extensions/PanelSelectionHandler.cs | 2 - .../Extensions/WindowResizeBehavior.cs | 10 - .../WpfDesign.Designer/Project/Func.cs | 2 + .../Project/Services/CreateComponentTool.cs | 3 - .../Project/Services/DragMoveMouseGesture.cs | 2 +- .../Project/Services/SelectionService.cs | 2 +- .../Project/SharedInstances.cs | 24 +++ .../Project/WpfDesign.Designer.csproj | 4 + .../Project/Xaml/XamlDesignItem.cs | 5 +- .../XamlModelCollectionElementsCollection.cs | 4 + .../Project/Xaml/XamlModelProperty.cs | 4 +- .../Project/CollectionElementsCollection.cs | 2 +- .../Project/CollectionSupport.cs | 9 + .../WpfDesign.XamlDom/Project/XamlParser.cs | 4 +- .../Project/XamlPropertyInfo.cs | 16 -- .../Project/Extensions/ExtensionManager.cs | 4 +- .../WpfDesign/Project/PlacementAlignment.cs | 4 +- .../WpfDesign/Project/PlacementType.cs | 4 +- 24 files changed, 462 insertions(+), 68 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridAdornerProvider.cs create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/SharedInstances.cs diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml index eb2dc22405..eda336f9b5 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml @@ -30,13 +30,12 @@ - - - - - - - + + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml index f70b22b5fb..a61a9ac100 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml @@ -66,7 +66,7 @@ - + + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs new file mode 100644 index 0000000000..5eddad80b5 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs @@ -0,0 +1,195 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using ICSharpCode.WpfDesign.Adorners; +using ICSharpCode.WpfDesign.Extensions; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Shapes; +using System.Windows.Media; +using System.Windows.Input; + +namespace ICSharpCode.WpfDesign.Designer.Controls +{ + /// + /// Adorner that displays the blue bar next to grids that can be used to create new rows/column. + /// + public class GridRailAdorner : Control + { + static GridRailAdorner() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(GridRailAdorner), new FrameworkPropertyMetadata(typeof(GridRailAdorner))); + } + + readonly DesignItem gridItem; + readonly Grid grid; + readonly AdornerPanel adornerPanel; + readonly GridSplitterAdorner previewAdorner; + readonly Orientation orientation; + + public const double RailSize = 10; + public const double SplitterWidth = 10; + + public GridRailAdorner(DesignItem gridItem, AdornerPanel adornerPanel, Orientation orientation) + { + Debug.Assert(gridItem != null); + Debug.Assert(adornerPanel != null); + + this.gridItem = gridItem; + this.grid = (Grid)gridItem.Component; + this.adornerPanel = adornerPanel; + this.orientation = orientation; + + if (orientation == Orientation.Horizontal) { + this.Height = RailSize; + previewAdorner = new GridColumnSplitterAdorner(); + } else { // vertical + this.Width = RailSize; + previewAdorner = new GridRowSplitterAdorner(); + } + previewAdorner.IsPreview = true; + previewAdorner.IsHitTestVisible = false; + } + + #region Handle mouse events to add a new row/column + protected override void OnMouseEnter(MouseEventArgs e) + { + base.OnMouseEnter(e); + adornerPanel.Children.Add(previewAdorner); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + RelativePlacement rp = new RelativePlacement(); + if (orientation == Orientation.Vertical) { + rp.XOffset = -RailSize; + rp.WidthOffset = RailSize; + rp.WidthRelativeToContentWidth = 1; + rp.HeightOffset = SplitterWidth; + rp.YOffset = e.GetPosition(this).Y - SplitterWidth / 2; + } else { + rp.YOffset = -RailSize; + rp.HeightOffset = RailSize; + rp.HeightRelativeToContentHeight = 1; + rp.WidthOffset = SplitterWidth; + rp.XOffset = e.GetPosition(this).X - SplitterWidth / 2; + } + AdornerPanel.SetPlacement(previewAdorner, rp); + } + + protected override void OnMouseLeave(MouseEventArgs e) + { + base.OnMouseLeave(e); + adornerPanel.Children.Remove(previewAdorner); + } + + protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonDown(e); + e.Handled = true; + adornerPanel.Children.Remove(previewAdorner); + if (orientation == Orientation.Vertical) { + using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid row")) { + DesignItemProperty rowCollection = gridItem.Properties["RowDefinitions"]; + if (rowCollection.CollectionElements.Count == 0) { + DesignItem firstRow = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition()); + rowCollection.CollectionElements.Add(firstRow); + grid.UpdateLayout(); // let WPF assign firstRow.ActualHeight + } + double insertionPosition = e.GetPosition(this).Y; + for (int i = 0; i < grid.RowDefinitions.Count; i++) { + RowDefinition row = grid.RowDefinitions[i]; + if (row.Offset > insertionPosition) continue; + if (row.Offset + row.ActualHeight < insertionPosition) continue; + + // split row + GridLength oldLength = (GridLength)row.GetValue(RowDefinition.HeightProperty); + GridLength newLength1, newLength2; + SplitLength(oldLength, insertionPosition - row.Offset, row.ActualHeight, out newLength1, out newLength2); + DesignItem newRowDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition()); + rowCollection.CollectionElements.Insert(i + 1, newRowDefinition); + rowCollection.CollectionElements[i].Properties[RowDefinition.HeightProperty].SetValue(newLength1); + newRowDefinition.Properties[RowDefinition.HeightProperty].SetValue(newLength2); + changeGroup.Commit(); + break; + } + } + } else { + using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid column")) { + DesignItemProperty columnCollection = gridItem.Properties["ColumnDefinitions"]; + if (columnCollection.CollectionElements.Count == 0) { + DesignItem firstColumn = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition()); + columnCollection.CollectionElements.Add(firstColumn); + grid.UpdateLayout(); // let WPF assign firstColumn.ActualWidth + } + double insertionPosition = e.GetPosition(this).X; + for (int i = 0; i < grid.ColumnDefinitions.Count; i++) { + ColumnDefinition column = grid.ColumnDefinitions[i]; + if (column.Offset > insertionPosition) continue; + if (column.Offset + column.ActualWidth < insertionPosition) continue; + + // split column + GridLength oldLength = (GridLength)column.GetValue(ColumnDefinition.WidthProperty); + GridLength newLength1, newLength2; + SplitLength(oldLength, insertionPosition - column.Offset, column.ActualWidth, out newLength1, out newLength2); + columnCollection.CollectionElements[i].Properties[ColumnDefinition.WidthProperty].SetValue(newLength1); + DesignItem newColumnDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition()); + newColumnDefinition.Properties[ColumnDefinition.WidthProperty].SetValue(newLength2); + columnCollection.CollectionElements.Insert(i + 1, newColumnDefinition); + changeGroup.Commit(); + break; + } + } + } + } + + void SplitLength(GridLength oldLength, double insertionPosition, double oldActualValue, + out GridLength newLength1, out GridLength newLength2) + { + if (oldLength.IsAuto) { + oldLength = new GridLength(oldActualValue); + } + double percentage = insertionPosition / oldActualValue; + newLength1 = new GridLength(oldLength.Value * percentage, oldLength.GridUnitType); + newLength2 = new GridLength(oldLength.Value - newLength1.Value, oldLength.GridUnitType); + } + #endregion + } + + public class GridSplitterAdorner : Control + { + public static readonly DependencyProperty IsPreviewProperty + = DependencyProperty.Register("IsPreview", typeof(bool), typeof(GridSplitterAdorner), new PropertyMetadata(SharedInstances.BoxedFalse)); + + public bool IsPreview { + get { return (bool)GetValue(IsPreviewProperty); } + set { SetValue(IsPreviewProperty, SharedInstances.Box(value)); } + } + } + + public class GridRowSplitterAdorner : GridSplitterAdorner + { + static GridRowSplitterAdorner() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(GridRowSplitterAdorner), new FrameworkPropertyMetadata(typeof(GridRowSplitterAdorner))); + CursorProperty.OverrideMetadata(typeof(GridRowSplitterAdorner), new FrameworkPropertyMetadata(Cursors.SizeNS)); + } + } + + public class GridColumnSplitterAdorner : GridSplitterAdorner + { + static GridColumnSplitterAdorner() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(GridColumnSplitterAdorner), new FrameworkPropertyMetadata(typeof(GridColumnSplitterAdorner))); + CursorProperty.OverrideMetadata(typeof(GridColumnSplitterAdorner), new FrameworkPropertyMetadata(Cursors.SizeWE)); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs index b4c07fdaf8..e5e3c825cf 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs @@ -28,11 +28,11 @@ namespace ICSharpCode.WpfDesign.Designer.Controls //This style is defined in themes\generic.xaml DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(typeof(WindowClone))); - Control.IsTabStopProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(false)); + Control.IsTabStopProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(SharedInstances.BoxedFalse)); KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle)); KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle)); KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle)); - FocusManager.IsFocusScopeProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(true)); + FocusManager.IsFocusScopeProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(SharedInstances.BoxedTrue)); } /// @@ -40,7 +40,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls /// public bool AllowsTransparency { get { return (bool)GetValue(Window.AllowsTransparencyProperty); } - set { SetValue(Window.AllowsTransparencyProperty, value); } + set { SetValue(Window.AllowsTransparencyProperty, SharedInstances.Box(value)); } } /// @@ -94,7 +94,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls /// public bool ShowInTaskbar { get { return (bool)GetValue(Window.ShowInTaskbarProperty); } - set { SetValue(Window.ShowInTaskbarProperty, value); } + set { SetValue(Window.ShowInTaskbarProperty, SharedInstances.Box(value)); } } /// @@ -127,7 +127,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls /// public bool Topmost { get { return (bool)GetValue(Window.TopmostProperty); } - set { SetValue(Window.TopmostProperty, value); } + set { SetValue(Window.TopmostProperty, SharedInstances.Box(value)); } } WindowStartupLocation windowStartupLocation; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs index c800581d1e..7111d608a8 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs @@ -22,7 +22,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions [ExtensionFor(typeof(Canvas))] public sealed class CanvasPlacementSupport : BehaviorExtension, IPlacementBehavior { - /// protected override void OnInitialized() { base.OnInitialized(); @@ -31,7 +30,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions GrayOutDesignerExceptActiveArea grayOut; - /// public bool CanPlace(ICollection child, PlacementType type, PlacementAlignment position) { return type == PlacementType.Resize || type == PlacementType.Move @@ -39,7 +37,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions || type == PlacementType.AddItem; } - /// public Rect GetPosition(PlacementOperation operation, DesignItem childItem) { UIElement child = childItem.View; @@ -64,7 +61,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions return v; } - /// public void SetPosition(PlacementInformation info) { UIElement child = info.Item.View; @@ -83,7 +79,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } - /// public void BeginPlacement(PlacementOperation op) { if (op.Type == PlacementType.Move || op.Type == PlacementType.Resize) { @@ -91,19 +86,16 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } - /// public void EndPlacement(PlacementOperation op) { GrayOutDesignerExceptActiveArea.Stop(ref grayOut); } - /// public bool CanLeaveContainer(PlacementOperation operation) { return true; } - /// public void LeaveContainer(PlacementOperation operation) { EndPlacement(operation); @@ -114,13 +106,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } - /// public bool CanEnterContainer(PlacementOperation operation) { return true; } - /// public void EnterContainer(PlacementOperation operation) { foreach (PlacementInformation info in operation.PlacedItems) { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridAdornerProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridAdornerProvider.cs new file mode 100644 index 0000000000..6937471573 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridAdornerProvider.cs @@ -0,0 +1,130 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using ICSharpCode.WpfDesign.Adorners; +using ICSharpCode.WpfDesign.Extensions; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Shapes; +using System.Windows.Media; +using System.Windows.Threading; +using ICSharpCode.WpfDesign.Designer.Controls; + +namespace ICSharpCode.WpfDesign.Designer.Extensions +{ + /// + /// Allows arranging the rows/column on a grid. + /// + [ExtensionFor(typeof(Grid))] + public class GridAdornerProvider : PrimarySelectionAdornerProvider + { + sealed class RowSplitterPlacement : AdornerPlacement + { + readonly RowDefinition row; + public RowSplitterPlacement(RowDefinition row) { this.row = row; } + + public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize) + { + adorner.Arrange(new Rect(-GridRailAdorner.RailSize, + row.Offset - GridRailAdorner.SplitterWidth / 2, + GridRailAdorner.RailSize + adornedElementSize.Width, + GridRailAdorner.SplitterWidth)); + } + } + + sealed class ColumnSplitterPlacement : AdornerPlacement + { + readonly ColumnDefinition column; + public ColumnSplitterPlacement(ColumnDefinition column) { this.column = column; } + + public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize) + { + adorner.Arrange(new Rect(column.Offset - GridRailAdorner.SplitterWidth / 2, + -GridRailAdorner.RailSize, + GridRailAdorner.SplitterWidth, + GridRailAdorner.RailSize + adornedElementSize.Height)); + } + } + + AdornerPanel adornerPanel = new AdornerPanel(); + GridRailAdorner topBar, leftBar; + + protected override void OnInitialized() + { + leftBar = new GridRailAdorner(this.ExtendedItem, adornerPanel, Orientation.Vertical); + topBar = new GridRailAdorner(this.ExtendedItem, adornerPanel, Orientation.Horizontal); + + AdornerPanel.SetPlacement(leftBar, new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Stretch)); + AdornerPanel.SetPlacement(topBar, new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Top)); + + adornerPanel.Children.Add(leftBar); + adornerPanel.Children.Add(topBar); + this.Adorners.Add(adornerPanel); + + CreateSplitter(); + this.ExtendedItem.PropertyChanged += OnPropertyChanged; + + base.OnInitialized(); + } + + protected override void OnRemove() + { + this.ExtendedItem.PropertyChanged -= OnPropertyChanged; + base.OnRemove(); + } + + void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == "RowDefinitions" || e.PropertyName == "ColumnDefinitions") { + CreateSplitter(); + } + } + + readonly List splitterList = new List(); + /// + /// flag used to unsure that the asynchronus splitter creation is only enqueued once + /// + bool requireSplitterRecreation; + + void CreateSplitter() + { + if (requireSplitterRecreation) return; + requireSplitterRecreation = true; + + // splitter creation is asynchronous to prevent unnecessary splitter re-creation when multiple + // changes to the collection are done. + // It also ensures that the Offset property of new rows/columns is initialized when the splitter + // is added. + Dispatcher.CurrentDispatcher.BeginInvoke( + DispatcherPriority.Loaded, // Loaded = after layout, but before input + (Action)delegate { + requireSplitterRecreation = false; + foreach (GridSplitterAdorner splitter in splitterList) { + adornerPanel.Children.Remove(splitter); + } + splitterList.Clear(); + Grid grid = (Grid)this.ExtendedItem.Component; + for (int i = 1; i < grid.RowDefinitions.Count; i++) { + RowDefinition row = grid.RowDefinitions[i]; + GridRowSplitterAdorner splitter = new GridRowSplitterAdorner(); + AdornerPanel.SetPlacement(splitter, new RowSplitterPlacement(row)); + adornerPanel.Children.Add(splitter); + splitterList.Add(splitter); + } + for (int i = 1; i < grid.ColumnDefinitions.Count; i++) { + ColumnDefinition column = grid.ColumnDefinitions[i]; + GridColumnSplitterAdorner splitter = new GridColumnSplitterAdorner(); + AdornerPanel.SetPlacement(splitter, new ColumnSplitterPlacement(column)); + adornerPanel.Children.Add(splitter); + splitterList.Add(splitter); + } + }); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs index 7ca1faf419..399cda0607 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs @@ -26,14 +26,12 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions [ExtensionFor(typeof(Panel))] public class PanelSelectionHandler : BehaviorExtension, IHandlePointerToolMouseDown { - /// protected override void OnInitialized() { base.OnInitialized(); this.ExtendedItem.AddBehavior(typeof(IHandlePointerToolMouseDown), this); } - /// public void HandleSelectionMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e, DesignPanelHitTestResult result) { new RangeSelectionGesture(result.ModelHit).Start(designPanel, e); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/WindowResizeBehavior.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/WindowResizeBehavior.cs index 558138c9c9..4d7eb67388 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/WindowResizeBehavior.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/WindowResizeBehavior.cs @@ -18,14 +18,12 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions [ExtensionFor(typeof(Window))] public class WindowResizeBehavior : BehaviorExtension, IRootPlacementBehavior { - /// protected override void OnInitialized() { base.OnInitialized(); this.ExtendedItem.AddBehavior(typeof(IRootPlacementBehavior), this); } - /// public bool CanPlace(ICollection children, PlacementType type, PlacementAlignment position) { return type == PlacementType.Resize && @@ -35,24 +33,20 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } - /// public void BeginPlacement(PlacementOperation operation) { } - /// public void EndPlacement(PlacementOperation operation) { } - /// public Rect GetPosition(PlacementOperation operation, DesignItem childItem) { UIElement child = childItem.View; return new Rect(0, 0, ModelTools.GetWidth(child), ModelTools.GetHeight(child)); } - /// public void SetPosition(PlacementInformation info) { UIElement element = info.Item.View; @@ -65,25 +59,21 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } - /// public bool CanLeaveContainer(PlacementOperation operation) { return false; } - /// public void LeaveContainer(PlacementOperation operation) { throw new NotSupportedException(); } - /// public bool CanEnterContainer(PlacementOperation operation) { return false; } - /// public void EnterContainer(PlacementOperation operation) { throw new NotSupportedException(); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs index d4d868ce54..a9af3278a7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs @@ -11,6 +11,8 @@ using System.Collections.Generic; namespace ICSharpCode.WpfDesign.Designer { + delegate void Action(); + // Static helpers that should become extension methods in the future static class Func { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs index df4230ab60..a563cbd691 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs @@ -38,12 +38,10 @@ namespace ICSharpCode.WpfDesign.Designer.Services get { return componentType; } } - /// public Cursor Cursor { get { return null; } } - /// public void Activate(IDesignPanel designPanel) { designPanel.MouseDown += OnMouseDown; @@ -51,7 +49,6 @@ namespace ICSharpCode.WpfDesign.Designer.Services designPanel.Drop += OnDrop; } - /// public void Deactivate(IDesignPanel designPanel) { designPanel.MouseDown -= OnMouseDown; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs index 3290d764b4..f11c386539 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs @@ -36,7 +36,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services selectedItems = clickedOn.Services.Selection.SelectedItems; if (!selectedItems.Contains(clickedOn)) - selectedItems = new DesignItem[0]; + selectedItems = SharedInstances.EmptyDesignItemArray; } protected override void OnDragStarted(MouseEventArgs e) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/SelectionService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/SelectionService.cs index 514551b81a..2bd569477f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/SelectionService.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/SelectionService.cs @@ -52,7 +52,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services public void SetSelectedComponents(ICollection components, SelectionTypes selectionType) { if (components == null) - components = new DesignItem[0]; + components = SharedInstances.EmptyDesignItemArray; if (SelectionChanging != null) SelectionChanging(this, EventArgs.Empty); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/SharedInstances.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/SharedInstances.cs new file mode 100644 index 0000000000..11b2906382 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/SharedInstances.cs @@ -0,0 +1,24 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace ICSharpCode.WpfDesign.Designer +{ + static class SharedInstances + { + internal static readonly object BoxedTrue = true; + internal static readonly object BoxedFalse = false; + internal static readonly object[] EmptyObjectArray = new object[0]; + internal static readonly DesignItem[] EmptyDesignItemArray = new DesignItem[0]; + + internal static object Box(bool value) + { + return value ? BoxedTrue : BoxedFalse; + } + } +} 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 967a7c2102..8e79ce8ae2 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -12,6 +12,7 @@ false ..\..\..\..\..\..\AddIns\AddIns\DisplayBindings\WpfDesign\ ..\..\..\..\..\..\AddIns\AddIns\DisplayBindings\WpfDesign\ICSharpCode.WpfDesign.Designer.xml + 1591 true @@ -58,6 +59,7 @@ + @@ -71,6 +73,7 @@ + @@ -94,6 +97,7 @@ + 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 b8289765d1..d0cbf0f51c 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs @@ -122,9 +122,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml get { return _properties; } } - internal void NotifyPropertyChanged(string propertyName) + internal void NotifyPropertyChanged(XamlModelProperty property) { - OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + Debug.Assert(property != null); + OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(property.Name)); } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs index e185f98b39..12af67fec1 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs @@ -190,11 +190,13 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml public void Do() { collection.InsertInternal(index, item); + collection.modelProperty.DesignItem.NotifyPropertyChanged(collection.modelProperty); } public void Undo() { collection.RemoveInternal(index, item); + collection.modelProperty.DesignItem.NotifyPropertyChanged(collection.modelProperty); } } @@ -226,11 +228,13 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml public void Do() { collection.RemoveInternal(index, item); + collection.modelProperty.DesignItem.NotifyPropertyChanged(collection.modelProperty); } public void Undo() { collection.InsertInternal(index, item); + collection.modelProperty.DesignItem.NotifyPropertyChanged(collection.modelProperty); } } } 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 fbdb1b3f00..fea1b902b1 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs @@ -190,7 +190,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml _property.ValueOnInstance = value; _property.PropertyValue = newValue; - _designItem.NotifyPropertyChanged(this.Name); + _designItem.NotifyPropertyChanged(this); } public override void Reset() @@ -206,7 +206,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml { if (_property.IsSet) { _property.Reset(); - _designItem.NotifyPropertyChanged(this.Name); + _designItem.NotifyPropertyChanged(this); } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs index 96bc9613c3..d690e1a5b8 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs @@ -55,7 +55,7 @@ namespace ICSharpCode.WpfDesign.XamlDom { XamlPropertyInfo info = property.propertyInfo; object collection = info.GetValue(property.ParentObject.Instance); - info.AddValue(collection, item); + CollectionSupport.Insert(info.ReturnType, collection, item, index); item.ParentProperty = property; property.InsertNodeInCollection(item.GetNodeForCollection(), index); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs index aa6b868942..e4730774ea 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs @@ -44,6 +44,15 @@ namespace ICSharpCode.WpfDesign.XamlDom } } + public static void Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) + { + collectionType.InvokeMember( + "Insert", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, + null, collectionInstance, + new object[] { index, newElement.GetValueFor(null) }, + CultureInfo.InvariantCulture); + } + static readonly Type[] RemoveAtParameters = { typeof(int) }; public static bool RemoveItemAt(Type collectionType, object collectionInstance, int index) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs index 6334eeab25..0d9b40ef99 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs @@ -220,7 +220,7 @@ namespace ICSharpCode.WpfDesign.XamlDom XamlPropertyValue childValue = ParseValue(childNode); if (childValue != null) { if (defaultProperty != null && defaultProperty.IsCollection) { - defaultProperty.AddValue(defaultPropertyValue, childValue); + CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue); defaultCollectionProperty.ParserAddCollectionElement(null, childValue); } else { if (setDefaultValueTo != null) @@ -448,7 +448,7 @@ namespace ICSharpCode.WpfDesign.XamlDom XamlPropertyValue childValue = ParseValue(childNode); if (childValue != null) { if (propertyInfo.IsCollection) { - propertyInfo.AddValue(collectionInstance, childValue); + CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue); collectionProperty.ParserAddCollectionElement(element, childValue); } else { if (valueWasSet) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs index 25eca3b7f0..a641a91cdb 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs @@ -34,7 +34,6 @@ namespace ICSharpCode.WpfDesign.XamlDom public abstract bool IsCollection { get; } public virtual bool IsEvent { get { return false; } } public abstract string Category { get; } - internal abstract void AddValue(object collectionInstance, XamlPropertyValue newElement); } #region XamlDependencyPropertyInfo @@ -100,11 +99,6 @@ namespace ICSharpCode.WpfDesign.XamlDom { ((DependencyObject)instance).ClearValue(property); } - - internal override void AddValue(object collectionInstance, XamlPropertyValue newElement) - { - throw new NotSupportedException(); - } } #endregion @@ -173,11 +167,6 @@ namespace ICSharpCode.WpfDesign.XamlDom return CollectionSupport.IsCollectionType(_propertyDescriptor.PropertyType); } } - - internal override void AddValue(object collectionInstance, XamlPropertyValue newElement) - { - CollectionSupport.AddToCollection(_propertyDescriptor.PropertyType, collectionInstance, newElement); - } } #endregion @@ -243,11 +232,6 @@ namespace ICSharpCode.WpfDesign.XamlDom public override bool IsCollection { get { return false; } } - - internal override void AddValue(object collectionInstance, XamlPropertyValue newElement) - { - throw new NotSupportedException(); - } } #endregion } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs index ef44f0702b..82ba2f6133 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs @@ -216,6 +216,8 @@ namespace ICSharpCode.WpfDesign.Extensions #endregion #region Special extensions (Instance Factory) + static readonly object[] emptyObjectArray = new object[0]; + /// /// Create an instance of the specified type using the specified arguments. /// The instance is created using a CustomInstanceFactory registered for the type, @@ -226,7 +228,7 @@ namespace ICSharpCode.WpfDesign.Extensions if (instanceType == null) throw new ArgumentNullException("instanceType"); if (arguments == null) - arguments = new object[0]; + arguments = emptyObjectArray; foreach (Type extensionType in GetExtensionTypes(instanceType)) { if (typeof(CustomInstanceFactory).IsAssignableFrom(extensionType)) { CustomInstanceFactory factory = (CustomInstanceFactory)Activator.CreateInstance(extensionType); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementAlignment.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementAlignment.cs index 601aab7b3e..3e2ef60e1b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementAlignment.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementAlignment.cs @@ -61,7 +61,9 @@ namespace ICSharpCode.WpfDesign return this.horizontal == other.horizontal && this.vertical == other.vertical; } - /// + /// + /// Gets the hash code. + /// public override int GetHashCode() { unchecked { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs index 7df7171dc2..ce570d1d8e 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs @@ -56,7 +56,9 @@ namespace ICSharpCode.WpfDesign return new PlacementType(name); } - /// + /// + /// Gets the name used to register this PlacementType. + /// public override string ToString() { return name;