diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs
new file mode 100644
index 0000000000..7f1f612021
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs
@@ -0,0 +1,191 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using ICSharpCode.WpfDesign.Adorners;
+
+namespace ICSharpCode.WpfDesign.Designer.Controls
+{
+ ///
+ /// A control that displays adorner panels.
+ ///
+ sealed class AdornerLayer : Panel
+ {
+ #region AdornerPanelCollection
+ internal sealed class AdornerPanelCollection : ICollection
+ {
+ readonly AdornerLayer _layer;
+
+ public AdornerPanelCollection(AdornerLayer layer)
+ {
+ this._layer = layer;
+ }
+
+ public int Count {
+ get { return _layer.Children.Count; }
+ }
+
+ public bool IsReadOnly {
+ get { return false; }
+ }
+
+ public void Add(AdornerPanel item)
+ {
+ if (item == null)
+ throw new ArgumentNullException("item");
+
+ _layer.AddAdorner(item);
+ }
+
+ public void Clear()
+ {
+ _layer.ClearAdorners();
+ }
+
+ public bool Contains(AdornerPanel item)
+ {
+ if (item == null)
+ throw new ArgumentNullException("item");
+
+ return VisualTreeHelper.GetParent(item) == _layer;
+ }
+
+ public void CopyTo(AdornerPanel[] array, int arrayIndex)
+ {
+ Linq.ToArray(this).CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(AdornerPanel item)
+ {
+ if (item == null)
+ throw new ArgumentNullException("item");
+
+ return _layer.RemoveAdorner(item);
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ foreach (AdornerPanel panel in _layer.Children) {
+ yield return panel;
+ }
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return this.GetEnumerator();
+ }
+ }
+ #endregion
+
+ AdornerPanelCollection _adorners;
+ readonly UIElement _designPanel;
+
+ internal AdornerLayer(UIElement designPanel)
+ {
+ this._designPanel = designPanel;
+
+ _adorners = new AdornerPanelCollection(this);
+ ClearAdorners();
+ }
+
+ internal AdornerPanelCollection Adorners {
+ get {
+ return _adorners;
+ }
+ }
+
+ sealed class AdornerInfo
+ {
+ internal readonly List adorners = new List();
+ }
+
+ // adorned element => AdornerInfo
+ Dictionary _dict;
+
+ void ClearAdorners()
+ {
+ this.Children.Clear();
+ _dict = new Dictionary();
+ }
+
+ AdornerInfo GetAdornerInfo(UIElement adornedElement)
+ {
+ AdornerInfo info;
+ if (!_dict.TryGetValue(adornedElement, out info)) {
+ info = _dict[adornedElement] = new AdornerInfo();
+ }
+ return info;
+ }
+
+ AdornerInfo GetExistingAdornerInfo(UIElement adornedElement)
+ {
+ AdornerInfo info;
+ _dict.TryGetValue(adornedElement, out info);
+ return info;
+ }
+
+ void AddAdorner(AdornerPanel adornerPanel)
+ {
+ if (adornerPanel.AdornedElement == null)
+ throw new DesignerException("adornerPanel.AdornedElement must be set");
+
+ GetAdornerInfo(adornerPanel.AdornedElement).adorners.Add(adornerPanel);
+
+ UIElementCollection children = this.Children;
+ int i = 0;
+ for (i = 0; i < children.Count; i++) {
+ AdornerPanel p = (AdornerPanel)children[i];
+ if (p.Order.CompareTo(adornerPanel.Order) > 0) {
+ break;
+ }
+ }
+ children.Insert(i, adornerPanel);
+
+ this.InvalidateMeasure();
+ }
+
+ protected override Size MeasureOverride(Size availableSize)
+ {
+ Size infiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
+ foreach (AdornerPanel adorner in this.Children) {
+ adorner.Measure(infiniteSize);
+ }
+ return new Size(0, 0);
+ }
+
+ protected override Size ArrangeOverride(Size finalSize)
+ {
+ foreach (AdornerPanel adorner in this.Children) {
+ adorner.Arrange(new Rect(new Point(0, 0), adorner.DesiredSize));
+ adorner.RenderTransform = (Transform)adorner.AdornedElement.TransformToAncestor(_designPanel);
+ }
+ return finalSize;
+ }
+
+ bool RemoveAdorner(AdornerPanel adornerPanel)
+ {
+ if (adornerPanel.AdornedElement == null)
+ return false;
+
+ AdornerInfo info = GetExistingAdornerInfo(adornerPanel.AdornedElement);
+ if (info == null)
+ return false;
+
+ if (info.adorners.Remove(adornerPanel)) {
+ this.Children.Remove(adornerPanel);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs
index bcfdabd7af..efc1a5497e 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs
@@ -33,7 +33,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
}
///
- /// Gets the visual child the design surfaces uses to display itself.
+ /// Gets the visual child.
///
protected override Visual GetVisualChild(int index)
{
@@ -44,7 +44,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
}
///
- /// Gets the number of visual children the design surface has.
+ /// Gets the number of visual children.
///
protected override int VisualChildrenCount {
get { return _visualChild != null ? 1 : 0; }
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs
index 61f186020a..b8f95e81d2 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs
@@ -11,42 +11,106 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;
+using System.Collections.Generic;
using System.Windows.Threading;
using ICSharpCode.WpfDesign.Designer.Controls;
+using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign.Designer
{
- sealed class DesignPanel : SingleVisualChildElement, IDesignPanel
+ sealed class DesignPanel : Decorator, IDesignPanel
{
- sealed class InnerDesignPanel : SingleVisualChildElement
+ ///
+ /// this element is always hit (unless HitTestVisible is set to false)
+ ///
+ sealed class EatAllHitTestRequests : UIElement
{
- internal void SetElement(UIElement element)
+ protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters)
+ {
+ return new GeometryHitTestResult(this, IntersectionDetail.FullyContains);
+ }
+
+ protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
- this.VisualChild = element;
+ return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
}
DesignContext _context;
- InnerDesignPanel _innerDesignPanel;
- UIElement _designedElement;
+ EatAllHitTestRequests _eatAllHitTestRequests;
+ AdornerLayer _adornerLayer;
public DesignPanel()
{
this.Focusable = true;
-
- _innerDesignPanel = new InnerDesignPanel();
- this.VisualChild = _innerDesignPanel;
+ _eatAllHitTestRequests = new EatAllHitTestRequests();
+ _eatAllHitTestRequests.IsHitTestVisible = false;
+ _adornerLayer = new AdornerLayer(this);
}
- public UIElement DesignedElement {
+ #region Visual Child Management
+ public override UIElement Child {
+ get { return base.Child; }
+ set {
+ if (base.Child == value)
+ return;
+ if (value == null) {
+ // Child is being set from some value to null
+
+ // remove _adornerLayer and _eatAllHitTestRequests
+ RemoveVisualChild(_adornerLayer);
+ RemoveVisualChild(_eatAllHitTestRequests);
+ } else if (base.Child == null) {
+ // Child is being set from null to some value
+ AddVisualChild(_adornerLayer);
+ AddVisualChild(_eatAllHitTestRequests);
+ }
+ base.Child = value;
+ }
+ }
+
+ protected override Visual GetVisualChild(int index)
+ {
+ if (base.Child != null) {
+ if (index == 0)
+ return base.Child;
+ else if (index == 1)
+ return _eatAllHitTestRequests;
+ else if (index == 2)
+ return _adornerLayer;
+ }
+ return base.GetVisualChild(index);
+ }
+
+ protected override int VisualChildrenCount {
get {
- return _designedElement;
+ if (base.Child != null)
+ return 3;
+ else
+ return base.VisualChildrenCount;
}
- set {
- _designedElement = value;
- _innerDesignPanel.SetElement(value);
+ }
+
+ protected override Size MeasureOverride(Size constraint)
+ {
+ Size result = base.MeasureOverride(constraint);
+ if (this.Child != null) {
+ _adornerLayer.Measure(constraint);
+ _eatAllHitTestRequests.Measure(constraint);
+ }
+ return result;
+ }
+
+ protected override Size ArrangeOverride(Size arrangeSize)
+ {
+ Size result = base.ArrangeOverride(arrangeSize);
+ if (this.Child != null) {
+ _adornerLayer.Arrange(new Rect(new Point(0, 0), arrangeSize));
+ _eatAllHitTestRequests.Arrange(new Rect(new Point(0, 0), arrangeSize));
}
+ return result;
}
+ #endregion
///
/// Gets/Sets the design context.
@@ -61,16 +125,6 @@ namespace ICSharpCode.WpfDesign.Designer
get { return _context.Services.Tool; }
}
- protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
- {
- return new PointHitTestResult(this, hitTestParameters.HitPoint);
- }
-
- protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters)
- {
- return new GeometryHitTestResult(this, IntersectionDetail.NotCalculated);
- }
-
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
base.OnPreviewMouseDown(e);
@@ -98,7 +152,7 @@ namespace ICSharpCode.WpfDesign.Designer
DesignItem site = _context.Services.Component.GetDesignItem(originalSource);
if (site != null)
return site;
- if (originalSource == _innerDesignPanel)
+ if (originalSource == this)
return null;
DependencyObject dObj = originalSource as DependencyObject;
if (dObj == null)
@@ -128,14 +182,20 @@ namespace ICSharpCode.WpfDesign.Designer
{
if (_isInInputAction) throw new InvalidOperationException();
_isInInputAction = true;
- _innerDesignPanel.IsHitTestVisible = false;
+ _eatAllHitTestRequests.IsHitTestVisible = true;
}
void IDesignPanel.StopInputAction()
{
if (!_isInInputAction) throw new InvalidOperationException();
_isInInputAction = false;
- _innerDesignPanel.IsHitTestVisible = true;
+ _eatAllHitTestRequests.IsHitTestVisible = false;
+ }
+
+ public ICollection Adorners {
+ get {
+ return _adornerLayer.Adorners;
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs
index 45a8c1cf2d..a76ddc2fdb 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs
@@ -48,7 +48,7 @@ namespace ICSharpCode.WpfDesign.Designer
///
public UIElement DesignedElement {
get {
- return _designPanel.DesignedElement;
+ return _designPanel.Child;
}
}
@@ -71,9 +71,11 @@ namespace ICSharpCode.WpfDesign.Designer
void InitializeDesigner(DesignContext context)
{
+ context.Services.AddService(typeof(IDesignPanel), _designPanel);
+
_designContext = context;
_designPanel.Context = context;
- _designPanel.DesignedElement = context.RootItem.View;
+ _designPanel.Child = context.RootItem.View;
}
///
@@ -83,7 +85,7 @@ namespace ICSharpCode.WpfDesign.Designer
{
_designContext = null;
_designPanel.Context = null;
- _designPanel.DesignedElement = null;
+ _designPanel.Child = null;
}
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs
new file mode 100644
index 0000000000..b86a0ec701
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs
@@ -0,0 +1,43 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Windows.Media;
+using System.Windows.Shapes;
+using ICSharpCode.WpfDesign.Adorners;
+using ICSharpCode.WpfDesign.Extensions;
+using ICSharpCode.WpfDesign.Designer.Controls;
+using System.Windows;
+
+namespace ICSharpCode.WpfDesign.Designer.Extensions
+{
+ ///
+ /// Draws a dotted line around selected UIElements.
+ ///
+ [ExtensionFor(typeof(UIElement))]
+ public class SelectedElementRectangleExtension : SelectionAdornerProvider
+ {
+ ///
+ /// Creates a new SelectedElementRectangleExtension instance.
+ ///
+ public SelectedElementRectangleExtension()
+ {
+ Rectangle r = new Rectangle();
+ r.SnapsToDevicePixels = true;
+ r.Stroke = Brushes.Black;
+ r.StrokeDashCap = PenLineCap.Square;
+ r.StrokeDashArray = new DoubleCollection(new double[] { 0, 2 });
+ r.IsHitTestVisible = false;
+
+ Placement placement = new Placement();
+ placement.WidthRelativeToContentWidth = 1;
+ placement.HeightRelativeToContentHeight = 1;
+
+ this.AddAdorner(r, placement);
+ }
+ }
+}
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 17e09c9624..46de417382 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/SelectionService.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/SelectionService.cs
@@ -46,7 +46,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services
public void SetSelectedComponents(ICollection components)
{
- SetSelectedComponents(components, SelectionTypes.Auto);
+ SetSelectedComponents(components, SelectionTypes.Replace);
}
public void SetSelectedComponents(ICollection components, SelectionTypes selectionType)
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs
index 93ad29feb7..fa4d87d6cb 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs
@@ -10,9 +10,7 @@ using System.Windows.Input;
namespace ICSharpCode.WpfDesign.Designer.Services
{
- ///
- /// See for description.
- ///
+ // See IToolService for description.
sealed class DefaultToolService : IToolService
{
PointerTool _pointerTool;
@@ -57,11 +55,13 @@ namespace ICSharpCode.WpfDesign.Designer.Services
abstract class MouseGestureBase
{
protected IDesignPanel designPanel;
+ protected ServiceContainer services;
bool isStarted;
public void Start(IDesignPanel designPanel, MouseButtonEventArgs e)
{
this.designPanel = designPanel;
+ this.services = designPanel.Context.Services;
isStarted = true;
designPanel.StartInputAction();
RegisterEvents();
@@ -125,6 +125,12 @@ namespace ICSharpCode.WpfDesign.Designer.Services
protected override void OnStarted(MouseButtonEventArgs e)
{
base.OnStarted(e);
+ DesignItem item = designPanel.FindDesignedElementForOriginalSource(e.OriginalSource);
+ if (item != null) {
+ services.Selection.SetSelectedComponents(new DesignItem[] { item }, SelectionTypes.Auto);
+ } else {
+ services.Selection.SetSelectedComponents(new DesignItem[] { }, SelectionTypes.Auto);
+ }
}
protected override void OnStopped()
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 840b6ae382..220c6c03b5 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
@@ -56,8 +56,10 @@
Configuration\GlobalAssemblyInfo.cs
+
+
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
new file mode 100644
index 0000000000..cbd4e4beed
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
@@ -0,0 +1,117 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace ICSharpCode.WpfDesign.Adorners
+{
+ ///
+ /// Manages display of adorners on the design surface.
+ ///
+ public sealed class AdornerPanel : Panel
+ {
+ #region Attached Property Placement
+ ///
+ /// The dependency property used to store the placement of adorner visuals.
+ ///
+ public static readonly DependencyProperty PlacementProperty = DependencyProperty.RegisterAttached(
+ "Placement", typeof(Placement), typeof(AdornerPanel),
+ new FrameworkPropertyMetadata(new Placement(), FrameworkPropertyMetadataOptions.AffectsParentMeasure)
+ );
+
+ ///
+ /// Gets the placement of the specified adorner visual.
+ ///
+ public static Placement GetPlacement(Visual visual)
+ {
+ if (visual == null)
+ throw new ArgumentNullException("visual");
+ return (Placement)visual.GetValue(PlacementProperty);
+ }
+
+ ///
+ /// Sets the placement of the specified adorner visual.
+ ///
+ public static void SetPlacement(Visual visual, Placement placement)
+ {
+ if (visual == null)
+ throw new ArgumentNullException("visual");
+ if (placement == null)
+ throw new ArgumentNullException("placement");
+ visual.SetValue(PlacementProperty, placement);
+ }
+ #endregion
+
+ UIElement _adornedElement;
+ AdornerOrder _Order = AdornerOrder.Content;
+
+ public UIElement AdornedElement {
+ get { return _adornedElement; }
+ set { _adornedElement = value; }
+ }
+
+ public AdornerOrder Order {
+ get { return _Order; }
+ set { _Order = value; }
+ }
+
+ protected override Size MeasureOverride(Size availableSize)
+ {
+ if (this.AdornedElement != null) {
+ foreach (DependencyObject v in this.VisualChildren) {
+ UIElement e = v as UIElement;
+ if (e != null) {
+ e.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
+ }
+ }
+ return this.AdornedElement.RenderSize;
+ } else {
+ return base.MeasureOverride(availableSize);
+ }
+ }
+
+ protected override Size ArrangeOverride(Size finalSize)
+ {
+ foreach (UIElement element in base.InternalChildren) {
+ element.Arrange(new Rect(finalSize));
+ }
+ return finalSize;
+ }
+
+ private IEnumerable VisualChildren {
+ get {
+ int count = VisualTreeHelper.GetChildrenCount(this);
+ for (int i = 0; i < count; i++) {
+ yield return VisualTreeHelper.GetChild(this, i);
+ }
+ }
+ }
+ }
+
+ public struct AdornerOrder : IComparable
+ {
+ public static readonly AdornerOrder Background = new AdornerOrder(100);
+ public static readonly AdornerOrder Content = new AdornerOrder(200);
+ public static readonly AdornerOrder Foreground = new AdornerOrder(300);
+
+ int i;
+
+ public AdornerOrder(int i)
+ {
+ this.i = i;
+ }
+
+ public int CompareTo(AdornerOrder other)
+ {
+ return i.CompareTo(other.i);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProvider.cs
new file mode 100644
index 0000000000..43e0aa00e6
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProvider.cs
@@ -0,0 +1,145 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.ObjectModel;
+using System.Windows;
+using System.Windows.Media;
+using ICSharpCode.WpfDesign.Extensions;
+
+namespace ICSharpCode.WpfDesign.Adorners
+{
+ ///
+ /// Base class for extensions that present adorners on the screen.
+ ///
+ ///
+ /// About design-time adorners and their placement:
+ /// read http://myfun.spaces.live.com/blog/cns!AC1291870308F748!240.entry
+ /// and http://myfun.spaces.live.com/blog/cns!AC1291870308F748!242.entry
+ ///
+ public abstract class AdornerProvider : DefaultExtension
+ {
+ #region class AdornerCollection
+ ///
+ /// Describes a collection of adorner visuals.
+ ///
+ sealed class AdornerPanelCollection : Collection
+ {
+ readonly AdornerProvider _provider;
+
+ internal AdornerPanelCollection(AdornerProvider provider)
+ {
+ this._provider = provider;
+ }
+
+ ///
+ protected override void InsertItem(int index, AdornerPanel item)
+ {
+ base.InsertItem(index, item);
+ _provider.OnAdornerAdd(item);
+ }
+
+ ///
+ protected override void RemoveItem(int index)
+ {
+ _provider.OnAdornerRemove(base[index]);
+ base.RemoveItem(index);
+ }
+
+ ///
+ protected override void SetItem(int index, AdornerPanel item)
+ {
+ _provider.OnAdornerRemove(base[index]);
+ base.SetItem(index, item);
+ _provider.OnAdornerAdd(item);
+ }
+
+ ///
+ protected override void ClearItems()
+ {
+ foreach (AdornerPanel v in this) {
+ _provider.OnAdornerRemove(v);
+ }
+ base.ClearItems();
+ }
+ }
+ #endregion
+
+ AdornerPanelCollection _adorners;
+ bool isVisible;
+
+ ///
+ /// Creates a new AdornerProvider instance.
+ ///
+ public AdornerProvider()
+ {
+ _adorners = new AdornerPanelCollection(this);
+ }
+
+ ///
+ /// Is called after the ExtendedItem was set.
+ /// This methods displays the registered adorners
+ ///
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ isVisible = true;
+ foreach (AdornerPanel v in _adorners) {
+ OnAdornerAdd(v);
+ }
+ }
+
+ ///
+ /// Is called when the extension is removed.
+ /// This method hides the registered adorners.
+ ///
+ protected override void OnRemove()
+ {
+ base.OnRemove();
+ foreach (AdornerPanel v in _adorners) {
+ OnAdornerRemove(v);
+ }
+ isVisible = false;
+ }
+
+ ///
+ /// Gets the list of adorners displayed by this AdornerProvider.
+ ///
+ public Collection Adorners {
+ get { return _adorners; }
+ }
+
+ ///
+ /// Adds an UIElement as adorner with the specified placement.
+ ///
+ protected void AddAdorner(UIElement adorner, Placement placement)
+ {
+ AdornerPanel.SetPlacement(adorner, placement);
+ AdornerPanel p = new AdornerPanel();
+ p.Children.Add(adorner);
+ this.Adorners.Add(p);
+ }
+
+ internal void OnAdornerAdd(AdornerPanel item)
+ {
+ if (!isVisible) return;
+
+ item.AdornedElement = this.ExtendedItem.View;
+
+ IDesignPanel avs = Services.GetService();
+ avs.Adorners.Add(item);
+ }
+
+ internal void OnAdornerRemove(AdornerPanel item)
+ {
+ if (!isVisible) return;
+
+ IDesignPanel avs = Services.GetService();
+ avs.Adorners.Remove(item);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProviderClasses.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProviderClasses.cs
new file mode 100644
index 0000000000..a55146a917
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProviderClasses.cs
@@ -0,0 +1,50 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using ICSharpCode.WpfDesign.Extensions;
+
+namespace ICSharpCode.WpfDesign.Adorners
+{
+ // Some classes that derive from AdornerProvider to specify a certain ExtensionServer.
+
+ ///
+ /// An adorner extension that is attached permanently.
+ ///
+ [ExtensionServer(typeof(DefaultExtensionServer.Permanent))]
+ public abstract class PermanentAdornerProvider : AdornerProvider
+ {
+
+ }
+
+ ///
+ /// An adorner extension that is attached to selected components.
+ ///
+ [ExtensionServer(typeof(SelectionExtensionServer))]
+ public abstract class SelectionAdornerProvider : AdornerProvider
+ {
+
+ }
+
+ ///
+ /// An adorner extension that is attached to the primary selection.
+ ///
+ [ExtensionServer(typeof(PrimarySelectionExtensionServer))]
+ public abstract class PrimarySelectionAdornerProvider : AdornerProvider
+ {
+
+ }
+
+ ///
+ /// An adorner extension that is attached to the secondary selection.
+ ///
+ [ExtensionServer(typeof(SecondarySelectionExtensionServer))]
+ public abstract class SecondarySelectionAdornerProvider : AdornerProvider
+ {
+
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/Placement.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/Placement.cs
new file mode 100644
index 0000000000..c787fc5f37
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/Placement.cs
@@ -0,0 +1,150 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.ObjectModel;
+using System.Windows;
+using System.Windows.Media;
+
+namespace ICSharpCode.WpfDesign.Adorners
+{
+ // We have to support the different coordinate spaces as explained in
+ // http://myfun.spaces.live.com/blog/cns!AC1291870308F748!242.entry
+
+ ///
+ /// Defines how a design-time adorner is placed.
+ ///
+ public class Placement
+ {
+ PlacementSpace space = PlacementSpace.Render;
+
+ ///
+ /// Gets/Sets the space in which the adorner is placed.
+ ///
+ public PlacementSpace Space {
+ get { return space; }
+ set { space = value; }
+ }
+
+ double widthRelativeToDesiredWidth, heightRelativeToDesiredHeight;
+
+ ///
+ /// Gets/Sets the width of the adorner relative to the desired adorner width.
+ ///
+ public double WidthRelativeToDesiredWidth {
+ get { return widthRelativeToDesiredWidth; }
+ set { widthRelativeToDesiredWidth = value; }
+ }
+
+ ///
+ /// Gets/Sets the height of the adorner relative to the desired adorner height.
+ ///
+ public double HeightRelativeToDesiredHeight {
+ get { return heightRelativeToDesiredHeight; }
+ set { heightRelativeToDesiredHeight = value; }
+ }
+
+ double widthRelativeToContentWidth, heightRelativeToContentHeight;
+
+ ///
+ /// Gets/Sets the width of the adorner relative to the width of the adorned item.
+ ///
+ public double WidthRelativeToContentWidth {
+ get { return widthRelativeToContentWidth; }
+ set { widthRelativeToContentWidth = value; }
+ }
+
+ ///
+ /// Gets/Sets the height of the adorner relative to the height of the adorned item.
+ ///
+ public double HeightRelativeToContentHeight {
+ get { return heightRelativeToContentHeight; }
+ set { heightRelativeToContentHeight = value; }
+ }
+
+ double widthOffset, heightOffset;
+
+ ///
+ /// Gets/Sets an offset that is added to the adorner width for the size calculation.
+ ///
+ public double WidthOffset {
+ get { return widthOffset; }
+ set { widthOffset = value; }
+ }
+
+ ///
+ /// Gets/Sets an offset that is added to the adorner height for the size calculation.
+ ///
+ public double HeightOffset {
+ get { return heightOffset; }
+ set { heightOffset = value; }
+ }
+
+ Size CalculateSize(Visual adornerVisual, UIElement adornedElement)
+ {
+ Size size = new Size(widthOffset, heightOffset);
+ if (widthRelativeToDesiredWidth != 0 || heightRelativeToDesiredHeight != 0) {
+ UIElement adornerElement = adornerVisual as UIElement;
+ if (adornerElement == null) {
+ throw new DesignerException("Cannot calculate the size relative to the adorner's desired size if the adorner is not an UIElement.");
+ }
+ size.Width += widthRelativeToDesiredWidth * adornerElement.DesiredSize.Width;
+ size.Height += heightRelativeToDesiredHeight * adornerElement.DesiredSize.Height;
+ }
+ size.Width += widthRelativeToContentWidth * adornedElement.RenderSize.Width;
+ size.Height += heightRelativeToContentHeight * adornedElement.RenderSize.Height;
+ return size;
+ }
+ }
+
+ ///
+ /// Describes the space in which an adorner is placed.
+ ///
+ public enum PlacementSpace
+ {
+ ///
+ /// The adorner is affected by the render transform of the adorned element.
+ ///
+ Render,
+ ///
+ /// The adorner is affected by the layout transform of the adorned element.
+ ///
+ Layout,
+ ///
+ /// The adorner is not affected by transforms of designed controls.
+ ///
+ Designer
+ }
+
+ ///
+ /// The possible layers where adorners can be placed.
+ ///
+ public enum AdornerZLayer
+ {
+ ///
+ /// This layer is below the other adorner layers.
+ ///
+ Low,
+ ///
+ /// This layer is for normal background adorners.
+ ///
+ Normal,
+ ///
+ /// This layer is for selection adorners
+ ///
+ Selection,
+ ///
+ /// This layer is for primary selection adorners
+ ///
+ PrimarySelection,
+ ///
+ /// This layer is above the other layers.
+ /// It is used for temporary drawings, e.g. the selection frame while selecting multiple controls with the mouse.
+ ///
+ High
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
index ff9e19a9fd..504a3205d4 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
@@ -71,42 +71,56 @@ namespace ICSharpCode.WpfDesign
}
}
- internal void SetExtensionServers(ExtensionServer[] extensionServers)
+ internal void SetExtensionServers(ExtensionManager extensionManager, ExtensionServer[] extensionServers)
{
Debug.Assert(_extensionServers == null);
Debug.Assert(extensionServers != null);
_extensionServers = extensionServers;
_extensionServerIsApplied = new bool[extensionServers.Length];
+
+ for (int i = 0; i < _extensionServers.Length; i++) {
+ bool shouldApply = _extensionServers[i].ShouldApplyExtensions(this);
+ if (shouldApply != _extensionServerIsApplied[i]) {
+ _extensionServerIsApplied[i] = shouldApply;
+ ApplyUnapplyExtensionServer(extensionManager, shouldApply, _extensionServers[i]);
+ }
+ }
}
- internal void ApplyExtensions(ExtensionManager extensionManager)
+ internal void ReapplyExtensionServer(ExtensionManager extensionManager, ExtensionServer server)
{
- Debug.Assert(_extensionServers != null);
for (int i = 0; i < _extensionServers.Length; i++) {
- bool shouldApply = _extensionServers[i].ShouldApplyExtensions(this);
- if (shouldApply != _extensionServerIsApplied[i]) {
- ExtensionServer server = _extensionServers[i];
- if (shouldApply) {
- // add extensions
- foreach (Extension ext in extensionManager.CreateExtensions(server, this)) {
- _extensions.Add(new ExtensionEntry(ext, server));
- }
- } else {
- // remove extensions
- _extensions.RemoveAll(
- delegate (ExtensionEntry entry) {
- if (entry.Server == server) {
- server.RemoveExtension(entry.Extension);
- return true;
- } else {
- return false;
- }
- });
+ if (_extensionServers[i] == server) {
+ bool shouldApply = server.ShouldApplyExtensions(this);
+ if (shouldApply != _extensionServerIsApplied[i]) {
+ _extensionServerIsApplied[i] = shouldApply;
+ ApplyUnapplyExtensionServer(extensionManager, shouldApply, server);
}
}
}
}
+
+ private void ApplyUnapplyExtensionServer(ExtensionManager extensionManager, bool shouldApply, ExtensionServer server)
+ {
+ if (shouldApply) {
+ // add extensions
+ foreach (Extension ext in extensionManager.CreateExtensions(server, this)) {
+ _extensions.Add(new ExtensionEntry(ext, server));
+ }
+ } else {
+ // remove extensions
+ _extensions.RemoveAll(
+ delegate (ExtensionEntry entry) {
+ if (entry.Server == server) {
+ server.RemoveExtension(entry.Extension);
+ return true;
+ } else {
+ return false;
+ }
+ });
+ }
+ }
#endregion
#region Manage behavior
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs
index 06633b7497..e0a8486733 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs
@@ -13,68 +13,9 @@ namespace ICSharpCode.WpfDesign.Extensions
/// Base class for extensions that provide a behavior interface for the designed item.
/// These extensions are always loaded. They must have an parameter-less constructor.
///
- [ExtensionServer(typeof(BehaviorExtension.BehaviorExtensionServer))]
- public abstract class BehaviorExtension : Extension
+ [ExtensionServer(typeof(DefaultExtensionServer.Permanent))]
+ public abstract class BehaviorExtension : DefaultExtension
{
- DesignItem _extendedItem;
- ///
- /// Gets the item that is being extended by the BehaviorExtension.
- ///
- public DesignItem ExtendedItem {
- get {
- if (_extendedItem == null)
- throw new InvalidOperationException("Cannot access BehaviorExtension.ExtendedItem: " +
- "The property is not initialized yet. Please move initialization logic " +
- "that depends on ExtendedItem into the OnInitialized method.");
- return _extendedItem;
- }
- }
-
- ///
- /// Gets the design context of the extended item. "Context" is equivalent to "ExtendedItem.Context".
- ///
- public DesignContext Context {
- get {
- return this.ExtendedItem.Context;
- }
- }
-
- ///
- /// Gets the service container of the extended item. "Services" is equivalent to "ExtendedItem.Services".
- ///
- public ServiceContainer Services {
- get {
- return this.ExtendedItem.Services;
- }
- }
-
- ///
- /// Is called after the ExtendedItem was set.
- /// Override this method to register your behavior with the item.
- ///
- protected virtual void OnInitialized()
- {
- }
-
- sealed class BehaviorExtensionServer : ExtensionServer
- {
- public override bool ShouldApplyExtensions(DesignItem extendedItem)
- {
- return true;
- }
-
- public override Extension CreateExtension(Type extensionType, DesignItem extendedItem)
- {
- BehaviorExtension ext = (BehaviorExtension)Activator.CreateInstance(extensionType);
- ext._extendedItem = extendedItem;
- ext.OnInitialized();
- return ext;
- }
-
- public override void RemoveExtension(Extension extension)
- {
- }
- }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/DefaultExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/DefaultExtension.cs
new file mode 100644
index 0000000000..5194230e95
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/DefaultExtension.cs
@@ -0,0 +1,114 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Diagnostics;
+
+namespace ICSharpCode.WpfDesign.Extensions
+{
+ ///
+ /// Base class for extensions that have an parameter-less constructor and are initialized using the
+ /// OnInitialize method.
+ ///
+ public class DefaultExtension : Extension
+ {
+ DesignItem _extendedItem;
+
+ ///
+ /// Gets the item that is being extended by the BehaviorExtension.
+ ///
+ public DesignItem ExtendedItem {
+ get {
+ if (_extendedItem == null)
+ throw new InvalidOperationException("Cannot access BehaviorExtension.ExtendedItem: " +
+ "The property is not initialized yet. Please move initialization logic " +
+ "that depends on ExtendedItem into the OnInitialized method.");
+ return _extendedItem;
+ }
+ }
+
+ ///
+ /// Gets the design context of the extended item. "Context" is equivalent to "ExtendedItem.Context".
+ ///
+ public DesignContext Context {
+ get {
+ return this.ExtendedItem.Context;
+ }
+ }
+
+ ///
+ /// Gets the service container of the extended item. "Services" is equivalent to "ExtendedItem.Services".
+ ///
+ public ServiceContainer Services {
+ get {
+ return this.ExtendedItem.Services;
+ }
+ }
+
+ ///
+ /// Is called after the ExtendedItem was set.
+ /// Override this method to register your behavior with the item.
+ ///
+ protected virtual void OnInitialized()
+ {
+ }
+
+ ///
+ /// Is called when the extension is removed.
+ ///
+ protected virtual void OnRemove()
+ {
+ }
+
+ internal void CallOnRemove() { OnRemove(); }
+
+ internal void InitializeDefaultExtension(DesignItem extendedItem)
+ {
+ Debug.Assert(this._extendedItem == null);
+ Debug.Assert(extendedItem != null);
+
+ this._extendedItem = extendedItem;
+ OnInitialized();
+ }
+ }
+
+ ///
+ /// Base class for extension servers that create extensions that derive from .
+ ///
+ public abstract class DefaultExtensionServer : ExtensionServer
+ {
+ ///
+ /// Creates an instance of the DefaultExtension and calls OnInitialize on it.
+ ///
+ public override Extension CreateExtension(Type extensionType, DesignItem extendedItem)
+ {
+ DefaultExtension ext = (DefaultExtension)Activator.CreateInstance(extensionType);
+ ext.InitializeDefaultExtension(extendedItem);
+ return ext;
+ }
+
+ ///
+ /// Calls OnRemove() on the DefaultExtension.
+ ///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
+ public override void RemoveExtension(Extension extension)
+ {
+ Debug.Assert(extension != null);
+ Debug.Assert(extension is DefaultExtension);
+
+ ((DefaultExtension)extension).CallOnRemove();
+ }
+
+ internal sealed class Permanent : DefaultExtensionServer
+ {
+ public override bool ShouldApplyExtensions(DesignItem extendedItem)
+ {
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs
index 0bb2576001..95bad14414 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs
@@ -32,8 +32,17 @@ namespace ICSharpCode.WpfDesign.Extensions
void OnComponentRegistered(object sender, DesignItemEventArgs e)
{
- e.Item.SetExtensionServers(GetExtensionServersForItem(e.Item));
- e.Item.ApplyExtensions(this);
+ e.Item.SetExtensionServers(this, GetExtensionServersForItem(e.Item));
+ }
+
+ ///
+ /// Re-applies extensions from the ExtensionServer to the specified design items.
+ ///
+ public void ReapplyExtensions(IEnumerable items, ExtensionServer server)
+ {
+ foreach (DesignItem item in items) {
+ item.ReapplyExtensionServer(this, server);
+ }
}
#region Manage ExtensionEntries
@@ -173,10 +182,11 @@ namespace ICSharpCode.WpfDesign.Extensions
{
Debug.Assert(extensionType != null);
- foreach (ExtensionServerAttribute esa in extensionType.GetCustomAttributes(typeof(ExtensionServerAttribute), true)) {
- return GetExtensionServer(esa);
- }
- throw new DesignerException("Extension types must have a [ExtensionServer] attribute.");
+ object[] extensionServerAttributes = extensionType.GetCustomAttributes(typeof(ExtensionServerAttribute), true);
+ if (extensionServerAttributes.Length != 1)
+ throw new DesignerException("Extension types must have exactly one [ExtensionServer] attribute.");
+
+ return GetExtensionServer((ExtensionServerAttribute)extensionServerAttributes[0]);
}
///
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs
new file mode 100644
index 0000000000..76a602edc9
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs
@@ -0,0 +1,93 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace ICSharpCode.WpfDesign.Extensions
+{
+ ///
+ /// Applies an extension to the selected components.
+ ///
+ public class SelectionExtensionServer : DefaultExtensionServer
+ {
+ ///
+ /// Is called after the extension server is initialized and the Context property has been set.
+ ///
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ Services.Selection.SelectionChanged += OnSelectionChanged;
+ }
+
+ void OnSelectionChanged(object sender, DesignItemCollectionEventArgs e)
+ {
+ Services.ExtensionManager.ReapplyExtensions(e.Items, this);
+ }
+
+ ///
+ /// Gets if the item is selected.
+ ///
+ public override bool ShouldApplyExtensions(DesignItem extendedItem)
+ {
+ return Services.Selection.IsComponentSelected(extendedItem);
+ }
+ }
+
+ ///
+ /// Applies an extension to the selected components, but not to the primary selection.
+ ///
+ public class SecondarySelectionExtensionServer : SelectionExtensionServer
+ {
+ ///
+ /// Gets if the item is in the secondary selection.
+ ///
+ public override bool ShouldApplyExtensions(DesignItem extendedItem)
+ {
+ return base.ShouldApplyExtensions(extendedItem) && Services.Selection.PrimarySelection != extendedItem;
+ }
+ }
+
+ ///
+ /// Applies an extension to the primary selection.
+ ///
+ public class PrimarySelectionExtensionServer : DefaultExtensionServer
+ {
+ DesignItem oldPrimarySelection;
+
+ ///
+ /// Is called after the extension server is initialized and the Context property has been set.
+ ///
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged;
+ }
+
+ void OnPrimarySelectionChanged(object sender, EventArgs e)
+ {
+ DesignItem newPrimarySelection = this.Services.Selection.PrimarySelection;
+ if (oldPrimarySelection != newPrimarySelection) {
+ if (oldPrimarySelection == null) {
+ this.Services.ExtensionManager.ReapplyExtensions(new DesignItem[] { newPrimarySelection }, this);
+ } else if (newPrimarySelection == null) {
+ this.Services.ExtensionManager.ReapplyExtensions(new DesignItem[] { oldPrimarySelection }, this);
+ } else {
+ this.Services.ExtensionManager.ReapplyExtensions(new DesignItem[] { oldPrimarySelection, newPrimarySelection }, this);
+ }
+ oldPrimarySelection = newPrimarySelection;
+ }
+ }
+
+ ///
+ /// Gets if the item is the primary selection.
+ ///
+ public override bool ShouldApplyExtensions(DesignItem extendedItem)
+ {
+ return Services.Selection.PrimarySelection == extendedItem;
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs
index c6f916327f..a44c5423f5 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Windows;
+using System.Windows.Media;
namespace ICSharpCode.WpfDesign
{
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs
index 424d66fca1..e95641d582 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs
@@ -6,8 +6,10 @@
//
using System;
+using System.Collections.Generic;
using System.Windows.Input;
using System.Windows;
+using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign
{
@@ -118,6 +120,10 @@ namespace ICSharpCode.WpfDesign
///
DesignItem FindDesignedElementForOriginalSource(object originalSource);
+ ///
+ /// Gets the list of adorners displayed on the design panel.
+ ///
+ ICollection Adorners { get; }
// The following members were missing in , but of course
// are supported on the DesignPanel:
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj
index 649df1182b..3274ed8bee 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj
@@ -57,17 +57,23 @@
Configuration\GlobalAssemblyInfo.cs
+
+
+
+
+
+
@@ -78,5 +84,6 @@
+
\ No newline at end of file