Browse Source

Merge pull request #630 from jogibear9988/master

Few fixups...
pull/638/head
Andreas Weizel 11 years ago
parent
commit
9b51908248
  1. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/Options/WpfEditorOptions.cs
  2. 36
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs
  3. 350
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineExtensionBase.cs
  4. 457
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineHandlerExtension.cs
  5. 141
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs
  6. 859
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PolyLineHandlerExtension.cs
  7. 11
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs
  8. 11
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs
  9. 142
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DummyValueInsteadOfNullTypeDescriptionProvider.cs
  10. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/Options/WpfEditorOptions.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.WpfDesign.AddIn.Options
public static bool EnableAppXamlParsing { public static bool EnableAppXamlParsing {
get { get {
return SD.PropertyService.Get(EnableAppXamlParsingOptionName, false); return SD.PropertyService.Get(EnableAppXamlParsingOptionName, true);
} }
set { set {
SD.PropertyService.Set(EnableAppXamlParsingOptionName, value); SD.PropertyService.Set(EnableAppXamlParsingOptionName, value);

36
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs

@ -49,6 +49,7 @@ using ICSharpCode.WpfDesign.Designer.PropertyGrid;
using ICSharpCode.WpfDesign.Designer.Services; using ICSharpCode.WpfDesign.Designer.Services;
using ICSharpCode.WpfDesign.Designer.Xaml; using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.XamlDom; using ICSharpCode.WpfDesign.XamlDom;
using ICSharpCode.WpfDesign.AddIn.Options;
namespace ICSharpCode.WpfDesign.AddIn namespace ICSharpCode.WpfDesign.AddIn
{ {
@ -155,26 +156,27 @@ namespace ICSharpCode.WpfDesign.AddIn
} }
try{ try{
var appXaml = SD.ProjectService.CurrentProject.Items.FirstOrDefault(x=>x.FileName.GetFileName().ToLower() == ("app.xaml")); if (WpfEditorOptions.EnableAppXamlParsing) {
if (appXaml!=null){ var appXaml = SD.ProjectService.CurrentProject.Items.FirstOrDefault(x=>x.FileName.GetFileName().ToLower() == ("app.xaml"));
var f=appXaml as FileProjectItem; if (appXaml!=null){
OpenedFile a = SD.FileService.GetOrCreateOpenedFile(f.FileName); var f=appXaml as FileProjectItem;
OpenedFile a = SD.FileService.GetOrCreateOpenedFile(f.FileName);
var xml = XmlReader.Create(a.OpenRead()); var xml = XmlReader.Create(a.OpenRead());
var doc=new XmlDocument(); var doc=new XmlDocument();
doc.Load(xml); doc.Load(xml);
var node = doc.FirstChild.ChildNodes.Cast<XmlNode>().FirstOrDefault(x=>x.Name=="Application.Resources"); var node = doc.FirstChild.ChildNodes.Cast<XmlNode>().FirstOrDefault(x=>x.Name=="Application.Resources");
foreach (XmlAttribute att in doc.FirstChild.Attributes.Cast<XmlAttribute>().ToList()) foreach (XmlAttribute att in doc.FirstChild.Attributes.Cast<XmlAttribute>().ToList()) {
{ if (att.Name.StartsWith("xmlns"))
if (att.Name.StartsWith("xmlns")) node.Attributes.Append(att);
node.Attributes.Append(att); }
}
var appXamlXml = XmlReader.Create(new StringReader(node.InnerXml)); var appXamlXml = XmlReader.Create(new StringReader(node.InnerXml));
var parsed = XamlParser.Parse(appXamlXml, ((XamlDesignContext) designer.DesignContext).ParserSettings); var parsed = XamlParser.Parse(appXamlXml, ((XamlDesignContext) designer.DesignContext).ParserSettings);
var dict = (ResourceDictionary)parsed.RootInstance; var dict = (ResourceDictionary)parsed.RootInstance;
designer.DesignPanel.Resources.MergedDictionaries.Add(dict); designer.DesignPanel.Resources.MergedDictionaries.Add(dict);
}
} }
} catch (Exception ex) { } catch (Exception ex) {
LoggingService.Error("Error in loading app.xaml", ex); LoggingService.Error("Error in loading app.xaml", ex);

350
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineExtensionBase.cs

@ -1,11 +1,21 @@
/* // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
* Created by SharpDevelop. //
* User: trubra // Permission is hereby granted, free of charge, to any person obtaining a copy of this
* Date: 2014-12-22 // software and associated documentation files (the "Software"), to deal in the Software
* Time: 11:00 // without restriction, including without limitation the rights to use, copy, modify, merge,
* // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* To change this template use Tools | Options | Coding | Edit Standard Headers. // to whom the Software is furnished to do so, subject to the following conditions:
*/ //
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System; using System;
using ICSharpCode.WpfDesign.Designer.Controls; using ICSharpCode.WpfDesign.Designer.Controls;
using ICSharpCode.WpfDesign.Designer.Extensions; using ICSharpCode.WpfDesign.Designer.Extensions;
@ -25,166 +35,166 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
/// Description of LineExtensionBase. /// Description of LineExtensionBase.
/// </summary> /// </summary>
class Bounds class Bounds
{ {
public double X, Y, Left, Top; public double X, Y, Left, Top;
} }
/// <summary> /// <summary>
/// base class for the Line, Polyline and Polygon extension classes /// base class for the Line, Polyline and Polygon extension classes
/// </summary> /// </summary>
public class LineExtensionBase : SelectionAdornerProvider public class LineExtensionBase : SelectionAdornerProvider
{ {
internal AdornerPanel adornerPanel; internal AdornerPanel adornerPanel;
internal IEnumerable resizeThumbs; internal IEnumerable resizeThumbs;
/// <summary>An array containing this.ExtendedItem as only element</summary> /// <summary>An array containing this.ExtendedItem as only element</summary>
internal readonly DesignItem[] extendedItemArray = new DesignItem[1]; internal readonly DesignItem[] extendedItemArray = new DesignItem[1];
internal IPlacementBehavior resizeBehavior; internal IPlacementBehavior resizeBehavior;
internal PlacementOperation operation; internal PlacementOperation operation;
internal ChangeGroup changeGroup; internal ChangeGroup changeGroup;
private Canvas _surface; private Canvas _surface;
internal bool _isResizing; internal bool _isResizing;
private TextBlock _text; private TextBlock _text;
//private DesignPanel designPanel; //private DesignPanel designPanel;
/// <summary> /// <summary>
/// Gets whether this extension is resizing any element. /// Gets whether this extension is resizing any element.
/// </summary> /// </summary>
public bool IsResizing public bool IsResizing
{ {
get { return _isResizing; } get { return _isResizing; }
} }
/// <summary> /// <summary>
/// on creation add adornerlayer /// on creation add adornerlayer
/// </summary> /// </summary>
public LineExtensionBase() public LineExtensionBase()
{ {
_surface = new Canvas(); _surface = new Canvas();
adornerPanel = new AdornerPanel(); adornerPanel = new AdornerPanel();
adornerPanel.Order = AdornerOrder.Foreground; adornerPanel.Order = AdornerOrder.Foreground;
adornerPanel.Children.Add(_surface); adornerPanel.Children.Add(_surface);
Adorners.Add(adornerPanel); Adorners.Add(adornerPanel);
} }
#region eventhandlers #region eventhandlers
protected void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) protected void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
UpdateAdornerVisibility(); UpdateAdornerVisibility();
} }
protected override void OnRemove() protected override void OnRemove()
{ {
this.ExtendedItem.PropertyChanged -= OnPropertyChanged; this.ExtendedItem.PropertyChanged -= OnPropertyChanged;
this.Services.Selection.PrimarySelectionChanged -= OnPrimarySelectionChanged; this.Services.Selection.PrimarySelectionChanged -= OnPrimarySelectionChanged;
DependencyPropertyDescriptor.FromProperty(FrameworkElement.HeightProperty, typeof (Shape)) DependencyPropertyDescriptor.FromProperty(FrameworkElement.HeightProperty, typeof (Shape))
.RemoveValueChanged(ExtendedItem.View, (s, ev) => ResetWidthHeightProperties()); .RemoveValueChanged(ExtendedItem.View, (s, ev) => ResetWidthHeightProperties());
base.OnRemove(); base.OnRemove();
} }
protected void OnPrimarySelectionChanged(object sender, EventArgs e) protected void OnPrimarySelectionChanged(object sender, EventArgs e)
{ {
bool isPrimarySelection = this.Services.Selection.PrimarySelection == this.ExtendedItem; bool isPrimarySelection = this.Services.Selection.PrimarySelection == this.ExtendedItem;
if (isPrimarySelection) if (isPrimarySelection)
DependencyPropertyDescriptor.FromProperty(FrameworkElement.HeightProperty, typeof (Shape)) DependencyPropertyDescriptor.FromProperty(FrameworkElement.HeightProperty, typeof (Shape))
.AddValueChanged(ExtendedItem.View, (s, ev) => ResetWidthHeightProperties()); .AddValueChanged(ExtendedItem.View, (s, ev) => ResetWidthHeightProperties());
//foreach (ResizeThumb g in adornerPanel.Children) //foreach (ResizeThumb g in adornerPanel.Children)
//{ //{
// g.IsPrimarySelection = isPrimarySelection; // g.IsPrimarySelection = isPrimarySelection;
//} //}
} }
#endregion #endregion
protected void UpdateAdornerVisibility() protected void UpdateAdornerVisibility()
{ {
FrameworkElement fe = this.ExtendedItem.View as FrameworkElement; FrameworkElement fe = this.ExtendedItem.View as FrameworkElement;
foreach (ResizeThumb r in resizeThumbs) foreach (ResizeThumb r in resizeThumbs)
{ {
bool isVisible = resizeBehavior != null && bool isVisible = resizeBehavior != null &&
resizeBehavior.CanPlace(extendedItemArray, PlacementType.Resize, r.Alignment); resizeBehavior.CanPlace(extendedItemArray, PlacementType.Resize, r.Alignment);
r.Visibility = isVisible ? Visibility.Visible : Visibility.Hidden; r.Visibility = isVisible ? Visibility.Visible : Visibility.Hidden;
} }
} }
/// <summary> /// <summary>
/// Places resize thumbs at their respective positions /// Places resize thumbs at their respective positions
/// and streches out thumbs which are at the center of outline to extend resizability across the whole outline /// and streches out thumbs which are at the center of outline to extend resizability across the whole outline
/// </summary> /// </summary>
/// <param name="resizeThumb"></param> /// <param name="resizeThumb"></param>
/// <param name="alignment"></param> /// <param name="alignment"></param>
/// <param name="index">if using a polygon or multipoint adorner this is the index of the point in the Points array</param> /// <param name="index">if using a polygon or multipoint adorner this is the index of the point in the Points array</param>
/// <returns></returns> /// <returns></returns>
protected PointTrackerPlacementSupport Place(ref ResizeThumb resizeThumb, PlacementAlignment alignment, int index = -1) protected PointTrackerPlacementSupport Place(ref ResizeThumb resizeThumb, PlacementAlignment alignment, int index = -1)
{ {
PointTrackerPlacementSupport placement = new PointTrackerPlacementSupport(ExtendedItem.View as Shape, alignment, index); PointTrackerPlacementSupport placement = new PointTrackerPlacementSupport(ExtendedItem.View as Shape, alignment, index);
return placement; return placement;
} }
/// <summary> /// <summary>
/// forces redraw of shape /// forces redraw of shape
/// </summary> /// </summary>
protected void Invalidate() protected void Invalidate()
{ {
Shape s = ExtendedItem.View as Shape; Shape s = ExtendedItem.View as Shape;
if (s != null) if (s != null)
{ {
s.InvalidateVisual(); s.InvalidateVisual();
s.BringIntoView(); s.BringIntoView();
} }
} }
protected void SetSurfaceInfo(int x, int y, string s) protected void SetSurfaceInfo(int x, int y, string s)
{ {
if (_text == null) if (_text == null)
{ {
_text = new TextBlock(); _text = new TextBlock();
_surface.Children.Add(_text); _surface.Children.Add(_text);
} }
AdornerPanel ap = _surface.Parent as AdornerPanel; AdornerPanel ap = _surface.Parent as AdornerPanel;
_surface.Width = ap.Width; _surface.Width = ap.Width;
_surface.Height = ap.Height; _surface.Height = ap.Height;
_text.Text = s; _text.Text = s;
Canvas.SetLeft(_text, x); Canvas.SetLeft(_text, x);
Canvas.SetTop(_text, y); Canvas.SetTop(_text, y);
} }
protected void HideSizeAndShowHandles() protected void HideSizeAndShowHandles()
{ {
SizeDisplayExtension sizeDisplay = null; SizeDisplayExtension sizeDisplay = null;
MarginHandleExtension marginDisplay = null; MarginHandleExtension marginDisplay = null;
foreach (var extension in ExtendedItem.Extensions) foreach (var extension in ExtendedItem.Extensions)
{ {
if (extension is SizeDisplayExtension) if (extension is SizeDisplayExtension)
sizeDisplay = extension as SizeDisplayExtension; sizeDisplay = extension as SizeDisplayExtension;
if (extension is MarginHandleExtension) if (extension is MarginHandleExtension)
marginDisplay = extension as MarginHandleExtension; marginDisplay = extension as MarginHandleExtension;
} }
if (sizeDisplay != null) if (sizeDisplay != null)
{ {
sizeDisplay.HeightDisplay.Visibility = Visibility.Hidden; sizeDisplay.HeightDisplay.Visibility = Visibility.Hidden;
sizeDisplay.WidthDisplay.Visibility = Visibility.Hidden; sizeDisplay.WidthDisplay.Visibility = Visibility.Hidden;
} }
if (marginDisplay != null) if (marginDisplay != null)
{ {
marginDisplay.ShowHandles(); marginDisplay.ShowHandles();
} }
} }
protected void ResetWidthHeightProperties() protected void ResetWidthHeightProperties()
{ {
ExtendedItem.Properties.GetProperty(FrameworkElement.HeightProperty).Reset(); ExtendedItem.Properties.GetProperty(FrameworkElement.HeightProperty).Reset();
ExtendedItem.Properties.GetProperty(FrameworkElement.WidthProperty).Reset(); ExtendedItem.Properties.GetProperty(FrameworkElement.WidthProperty).Reset();
} }
} }
} }

457
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineHandlerExtension.cs

@ -1,11 +1,21 @@
/* // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
* Created by SharpDevelop. //
* User: trubra // Permission is hereby granted, free of charge, to any person obtaining a copy of this
* Date: 2014-12-22 // software and associated documentation files (the "Software"), to deal in the Software
* Time: 10:34 // without restriction, including without limitation the rights to use, copy, modify, merge,
* // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* To change this template use Tools | Options | Coding | Edit Standard Headers. // to whom the Software is furnished to do so, subject to the following conditions:
*/ //
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System; using System;
using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign; using ICSharpCode.WpfDesign;
@ -21,228 +31,221 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.WpfDesign.Designer.UIExtensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
/// <summary> /// <summary>
/// Description of LineHandlerExtension. /// Description of LineHandlerExtension.
/// </summary> /// </summary>
[ExtensionFor(typeof(Line), OverrideExtensions = new Type[] { typeof(ResizeThumbExtension), typeof(SelectedElementRectangleExtension), typeof(CanvasPositionExtension), typeof(QuickOperationMenuExtension), typeof(RotateThumbExtension), typeof(RenderTransformOriginExtension), typeof(InPlaceEditorExtension) })] [ExtensionFor(typeof(Line), OverrideExtensions = new Type[] { typeof(ResizeThumbExtension), typeof(SelectedElementRectangleExtension), typeof(CanvasPositionExtension), typeof(QuickOperationMenuExtension), typeof(RotateThumbExtension), typeof(RenderTransformOriginExtension), typeof(InPlaceEditorExtension), typeof(SkewThumbExtension) })]
internal class LineHandlerExtension : LineExtensionBase internal class LineHandlerExtension : LineExtensionBase
{ {
// //
private double CurrentX2; private double CurrentX2;
private double CurrentY2; private double CurrentY2;
private double CurrentLeft; private double CurrentLeft;
private double CurrentTop; private double CurrentTop;
//Size oldSize; //Size oldSize;
ZoomControl zoom; ZoomControl zoom;
protected ResizeThumb CreateThumb(PlacementAlignment alignment, Cursor cursor) protected ResizeThumb CreateThumb(PlacementAlignment alignment, Cursor cursor)
{ {
ResizeThumb resizeThumb = new ResizeThumb { Alignment = alignment, Cursor = cursor, IsPrimarySelection = true}; ResizeThumb resizeThumb = new ResizeThumb { Alignment = alignment, Cursor = cursor, IsPrimarySelection = true};
AdornerPanel.SetPlacement(resizeThumb, Place(ref resizeThumb, alignment)); AdornerPanel.SetPlacement(resizeThumb, Place(ref resizeThumb, alignment));
adornerPanel.Children.Add(resizeThumb); adornerPanel.Children.Add(resizeThumb);
DragListener drag = new DragListener(resizeThumb); DragListener drag = new DragListener(resizeThumb);
drag.Started += drag_Started; drag.Started += drag_Started;
drag.Changed += drag_Changed; drag.Changed += drag_Changed;
drag.Completed += drag_Completed; drag.Completed += drag_Completed;
return resizeThumb; return resizeThumb;
} }
protected Bounds CalculateDrawing(double x, double y, double left, double top, double xleft, double xtop) protected Bounds CalculateDrawing(double x, double y, double left, double top, double xleft, double xtop)
{ {
Double theta = (180 / Math.PI) * Math.Atan2(y, x); Double theta = (180 / Math.PI) * Math.Atan2(y, x);
double verticaloffset = Math.Abs(90 - Math.Abs(theta)); double verticaloffset = Math.Abs(90 - Math.Abs(theta));
if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)) if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ {
if (Math.Abs(theta) < 45 || Math.Abs(theta) > 135) if (Math.Abs(theta) < 45 || Math.Abs(theta) > 135)
{ {
y = 0; y = 0;
top = xtop; top = xtop;
} }
else if (verticaloffset < 45) else if (verticaloffset < 45)
{ {
x = 0; x = 0;
left = xleft; left = xleft;
} }
} }
else if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) else if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ {
if (verticaloffset < 10) if (verticaloffset < 10)
{ {
x = 0; x = 0;
left = xleft; left = xleft;
} }
else if (Math.Abs(theta) < 10 || Math.Abs(theta) > 170) else if (Math.Abs(theta) < 10 || Math.Abs(theta) > 170)
{ {
y = 0; y = 0;
top = xtop; top = xtop;
} }
} }
SetSurfaceInfo(0, 0, Math.Round((180 / Math.PI) * Math.Atan2(y, x), 0).ToString()); SetSurfaceInfo(0, 0, Math.Round((180 / Math.PI) * Math.Atan2(y, x), 0).ToString());
return new Bounds { X = Math.Round(x, 1), Y = Math.Round(y, 1), Left = Math.Round(left, 1), Top = Math.Round(top, 1) }; return new Bounds { X = Math.Round(x, 1), Y = Math.Round(y, 1), Left = Math.Round(left, 1), Top = Math.Round(top, 1) };
} }
#region eventhandlers #region eventhandlers
// TODO : Remove all hide/show extensions from here. // TODO : Remove all hide/show extensions from here.
protected virtual void drag_Started(DragListener drag) protected virtual void drag_Started(DragListener drag)
{ {
Line al = ExtendedItem.View as Line; Line al = ExtendedItem.View as Line;
CurrentX2 = al.X2; CurrentX2 = al.X2;
CurrentY2 = al.Y2; CurrentY2 = al.Y2;
CurrentLeft = (double)al.GetValue(Canvas.LeftProperty); CurrentLeft = (double)al.GetValue(Canvas.LeftProperty);
CurrentTop = (double)al.GetValue(Canvas.TopProperty); CurrentTop = (double)al.GetValue(Canvas.TopProperty);
var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel; var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel;
if (designPanel != null) zoom = designPanel.TryFindParent<ZoomControl>();
{
var p = VisualTreeHelper.GetParent(designPanel); if (resizeBehavior != null)
while (p != null && !(p is ZoomControl)) operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize);
{ else
p = VisualTreeHelper.GetParent(p); {
} changeGroup = this.ExtendedItem.Context.OpenGroup("Resize", extendedItemArray);
zoom = p as ZoomControl; }
} _isResizing = true;
if (resizeBehavior != null) (drag.Target as ResizeThumb).IsPrimarySelection = false;
operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize); }
else
{ protected virtual void drag_Changed(DragListener drag)
changeGroup = this.ExtendedItem.Context.OpenGroup("Resize", extendedItemArray); {
} Line al = ExtendedItem.View as Line;
_isResizing = true;
var alignment = (drag.Target as ResizeThumb).Alignment;
(drag.Target as ResizeThumb).IsPrimarySelection = false; var info = operation.PlacedItems[0];
} double dx = 0;
double dy = 0;
protected virtual void drag_Changed(DragListener drag)
{ if (zoom != null)
Line al = ExtendedItem.View as Line; {
dx = drag.Delta.X * (1 / zoom.CurrentZoom);
var alignment = (drag.Target as ResizeThumb).Alignment; dy = drag.Delta.Y * (1 / zoom.CurrentZoom);
var info = operation.PlacedItems[0]; }
double dx = 0; double top, left, x, y, xtop, xleft;
double dy = 0;
if (zoom != null) if (alignment == PlacementAlignment.TopLeft)
{ {
dx = drag.Delta.X * (1 / zoom.CurrentZoom); //normal values
dy = drag.Delta.Y * (1 / zoom.CurrentZoom); x = CurrentX2 - dx;
} y = CurrentY2 - dy;
double top, left, x, y, xtop, xleft; top = CurrentTop + dy;
left = CurrentLeft + dx;
if (alignment == PlacementAlignment.TopLeft) //values to use when keys are pressed
{ xtop = CurrentTop + CurrentY2;
//normal values xleft = CurrentLeft + CurrentX2;
x = CurrentX2 - dx;
y = CurrentY2 - dy; }
top = CurrentTop + dy; else
left = CurrentLeft + dx; {
x = CurrentX2 + dx;
//values to use when keys are pressed y = CurrentY2 + dy;
xtop = CurrentTop + CurrentY2; top = xtop = CurrentTop;
xleft = CurrentLeft + CurrentX2; left = xleft = CurrentLeft;
}
} Bounds position = CalculateDrawing(x, y, left, top, xleft, xtop);
else
{ ExtendedItem.Properties.GetProperty(Line.X1Property).SetValue(0);
x = CurrentX2 + dx; ExtendedItem.Properties.GetProperty(Line.Y1Property).SetValue(0);
y = CurrentY2 + dy; ExtendedItem.Properties.GetProperty(Line.X2Property).SetValue(position.X);
top = xtop = CurrentTop; ExtendedItem.Properties.GetProperty(Line.Y2Property).SetValue(position.Y);
left = xleft = CurrentLeft;
} if (operation != null)
Bounds position = CalculateDrawing(x, y, left, top, xleft, xtop); {
var result = info.OriginalBounds;
ExtendedItem.Properties.GetProperty(Line.X1Property).SetValue(0); result.X = position.Left;
ExtendedItem.Properties.GetProperty(Line.Y1Property).SetValue(0); result.Y = position.Top;
ExtendedItem.Properties.GetProperty(Line.X2Property).SetValue(position.X); result.Width = Math.Abs(position.X);
ExtendedItem.Properties.GetProperty(Line.Y2Property).SetValue(position.Y); result.Height = Math.Abs(position.Y);
if (operation != null) info.Bounds = result.Round();
{ operation.CurrentContainerBehavior.BeforeSetPosition(operation);
var result = info.OriginalBounds; operation.CurrentContainerBehavior.SetPosition(info);
result.X = position.Left; }
result.Y = position.Top; (drag.Target as ResizeThumb).InvalidateArrange();
result.Width = Math.Abs(position.X); ResetWidthHeightProperties();
result.Height = Math.Abs(position.Y); }
info.Bounds = result.Round(); protected virtual void drag_Completed(DragListener drag)
operation.CurrentContainerBehavior.BeforeSetPosition(operation); {
operation.CurrentContainerBehavior.SetPosition(info); if (operation != null)
} {
(drag.Target as ResizeThumb).InvalidateArrange(); if (drag.IsCanceled) operation.Abort();
ResetWidthHeightProperties(); else
} {
ResetWidthHeightProperties();
protected virtual void drag_Completed(DragListener drag)
{ operation.Commit();
if (operation != null) }
{ operation = null;
if (drag.IsCanceled) operation.Abort(); }
else else
{ {
ResetWidthHeightProperties(); if (drag.IsCanceled) changeGroup.Abort();
else changeGroup.Commit();
operation.Commit(); changeGroup = null;
} }
operation = null;
} _isResizing = false;
else (drag.Target as ResizeThumb).IsPrimarySelection = true;
{ HideSizeAndShowHandles();
if (drag.IsCanceled) changeGroup.Abort(); }
else changeGroup.Commit();
changeGroup = null; /// <summary>
} /// is invoked whenever a line is selected on the canvas, remember that the adorners are created for each line object and never destroyed
/// </summary>
_isResizing = false; protected override void OnInitialized()
(drag.Target as ResizeThumb).IsPrimarySelection = true; {
HideSizeAndShowHandles(); base.OnInitialized();
} if (ExtendedItem.Properties.GetProperty(Line.StrokeProperty).ValueOnInstance == null)
{
/// <summary> ExtendedItem.Properties[Shape.StrokeProperty].SetValue(Colors.Black);
/// is invoked whenever a line is selected on the canvas, remember that the adorners are created for each line object and never destroyed ExtendedItem.Properties[Shape.StrokeThicknessProperty].SetValue(2d);
/// </summary> ExtendedItem.Properties[Shape.StretchProperty].SetValue(Stretch.None);
protected override void OnInitialized() ExtendedItem.Properties.GetProperty(Line.X1Property).SetValue(0);
{ ExtendedItem.Properties.GetProperty(Line.Y1Property).SetValue(0);
base.OnInitialized(); ExtendedItem.Properties.GetProperty(Line.X2Property).SetValue(20);
if (ExtendedItem.Properties.GetProperty(Line.StrokeProperty).ValueOnInstance == null) ExtendedItem.Properties.GetProperty(Line.Y2Property).SetValue(20);
{ (ExtendedItem.View as Line).BringIntoView();
ExtendedItem.Properties[Shape.StrokeProperty].SetValue(Colors.Black); }
ExtendedItem.Properties[Shape.StrokeThicknessProperty].SetValue(2d);
ExtendedItem.Properties[Shape.StretchProperty].SetValue(Stretch.None); resizeThumbs = new ResizeThumb[]
ExtendedItem.Properties.GetProperty(Line.X1Property).SetValue(0); {
ExtendedItem.Properties.GetProperty(Line.Y1Property).SetValue(0); CreateThumb(PlacementAlignment.TopLeft, Cursors.SizeNWSE),
ExtendedItem.Properties.GetProperty(Line.X2Property).SetValue(20); CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE)
ExtendedItem.Properties.GetProperty(Line.Y2Property).SetValue(20); };
(ExtendedItem.View as Line).BringIntoView();
} extendedItemArray[0] = this.ExtendedItem;
resizeThumbs = new ResizeThumb[] Invalidate();
{ //ResetWidthHeightProperties();
CreateThumb(PlacementAlignment.TopLeft, Cursors.SizeNWSE),
CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE) this.ExtendedItem.PropertyChanged += OnPropertyChanged;
}; this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged;
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray);
extendedItemArray[0] = this.ExtendedItem; UpdateAdornerVisibility();
OnPrimarySelectionChanged(null, null);
Invalidate(); }
//ResetWidthHeightProperties();
#endregion
this.ExtendedItem.PropertyChanged += OnPropertyChanged; }
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged;
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray);
UpdateAdornerVisibility();
OnPrimarySelectionChanged(null, null);
}
#endregion
}
} }

141
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs

@ -79,6 +79,32 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
} }
} }
[ExtensionFor(typeof(ItemsControl))]
public sealed class TransparentControlsInstanceFactory : CustomInstanceFactory
{
Brush _transparentBrush = new SolidColorBrush(Colors.Transparent);
/// <summary>
/// Creates an instance of the specified type, passing the specified arguments to its constructor.
/// </summary>
public override object CreateInstance(Type type, params object[] arguments)
{
object instance = base.CreateInstance(type, arguments);
Control control = instance as Control;
if (control != null && (
type == typeof(ItemsControl))) {
if (control.Background == null) {
control.Background = _transparentBrush;
}
TypeDescriptionProvider provider = new DummyValueInsteadOfNullTypeDescriptionProvider(
TypeDescriptor.GetProvider(control), "Background", _transparentBrush);
TypeDescriptor.AddProvider(provider, control);
}
return instance;
}
}
[ExtensionFor(typeof(Border))] [ExtensionFor(typeof(Border))]
public sealed class BorderInstanceFactory : CustomInstanceFactory public sealed class BorderInstanceFactory : CustomInstanceFactory
{ {
@ -104,119 +130,4 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
return instance; return instance;
} }
} }
sealed class DummyValueInsteadOfNullTypeDescriptionProvider : TypeDescriptionProvider
{
// By using a TypeDescriptionProvider, we can intercept all access to the property that is
// using a PropertyDescriptor. WpfDesign.XamlDom uses a PropertyDescriptor for accessing
// properties (except for attached properties), so even DesignItemProperty/XamlProperty.ValueOnInstance
// will report null when the actual value is the dummy value.
readonly string _propertyName;
readonly object _dummyValue;
public DummyValueInsteadOfNullTypeDescriptionProvider(TypeDescriptionProvider existingProvider,
string propertyName, object dummyValue)
: base(existingProvider)
{
this._propertyName = propertyName;
this._dummyValue = dummyValue;
}
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new ShadowTypeDescriptor(this, base.GetTypeDescriptor(objectType, instance));
}
sealed class ShadowTypeDescriptor : CustomTypeDescriptor
{
readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent;
public ShadowTypeDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent,
ICustomTypeDescriptor existingDescriptor)
: base(existingDescriptor)
{
this._parent = parent;
}
public override PropertyDescriptorCollection GetProperties()
{
return Filter(base.GetProperties());
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return Filter(base.GetProperties(attributes));
}
PropertyDescriptorCollection Filter(PropertyDescriptorCollection properties)
{
PropertyDescriptor property = properties[_parent._propertyName];
if (property != null) {
if ((properties as System.Collections.IDictionary).IsReadOnly) {
properties = new PropertyDescriptorCollection(properties.Cast<PropertyDescriptor>().ToArray());
}
properties.Remove(property);
properties.Add(new ShadowPropertyDescriptor(_parent, property));
}
return properties;
}
}
sealed class ShadowPropertyDescriptor : PropertyDescriptor
{
readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent;
readonly PropertyDescriptor _baseDescriptor;
public ShadowPropertyDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent,
PropertyDescriptor existingDescriptor)
: base(existingDescriptor)
{
this._parent = parent;
this._baseDescriptor = existingDescriptor;
}
public override Type ComponentType {
get { return _baseDescriptor.ComponentType; }
}
public override bool IsReadOnly {
get { return _baseDescriptor.IsReadOnly; }
}
public override Type PropertyType {
get { return _baseDescriptor.PropertyType; }
}
public override bool CanResetValue(object component)
{
return _baseDescriptor.CanResetValue(component);
}
public override object GetValue(object component)
{
object value = _baseDescriptor.GetValue(component);
if (value == _parent._dummyValue)
return null;
else
return value;
}
public override void ResetValue(object component)
{
_baseDescriptor.SetValue(component, _parent._dummyValue);
}
public override void SetValue(object component, object value)
{
_baseDescriptor.SetValue(component, value ?? _parent._dummyValue);
}
public override bool ShouldSerializeValue(object component)
{
return _baseDescriptor.ShouldSerializeValue(component)
&& _baseDescriptor.GetValue(component) != _parent._dummyValue;
}
}
}
} }

859
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PolyLineHandlerExtension.cs

@ -1,11 +1,21 @@
/* // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
* Created by SharpDevelop. //
* User: trubra // Permission is hereby granted, free of charge, to any person obtaining a copy of this
* Date: 2014-12-22 // software and associated documentation files (the "Software"), to deal in the Software
* Time: 10:34 // without restriction, including without limitation the rights to use, copy, modify, merge,
* // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* To change this template use Tools | Options | Coding | Edit Standard Headers. // to whom the Software is furnished to do so, subject to the following conditions:
*/ //
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System; using System;
using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign; using ICSharpCode.WpfDesign;
@ -21,430 +31,423 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.WpfDesign.Designer.UIExtensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
/// <summary> /// <summary>
/// Description of PolyLineHandlerExtension. /// Description of PolyLineHandlerExtension.
/// </summary> /// </summary>
[ExtensionFor(typeof(Polyline), OverrideExtensions = new Type[] { typeof(ResizeThumbExtension), typeof(SelectedElementRectangleExtension), typeof(CanvasPositionExtension), typeof(QuickOperationMenuExtension), typeof(RotateThumbExtension), typeof(RenderTransformOriginExtension), typeof(InPlaceEditorExtension), typeof(SizeDisplayExtension) })] [ExtensionFor(typeof(Polyline), OverrideExtensions = new Type[] { typeof(ResizeThumbExtension), typeof(SelectedElementRectangleExtension), typeof(CanvasPositionExtension), typeof(QuickOperationMenuExtension), typeof(RotateThumbExtension), typeof(RenderTransformOriginExtension), typeof(InPlaceEditorExtension), typeof(SizeDisplayExtension), typeof(SkewThumbExtension) })]
internal class PolyLineHandlerExtension : LineExtensionBase, IKeyDown, IKeyUp internal class PolyLineHandlerExtension : LineExtensionBase, IKeyDown, IKeyUp
{ {
private readonly Dictionary<int, Bounds> _selectedThumbs = new Dictionary<int, Bounds>(); private readonly Dictionary<int, Bounds> _selectedThumbs = new Dictionary<int, Bounds>();
private bool _isDragging; private bool _isDragging;
ZoomControl _zoom; ZoomControl _zoom;
#region thumb methods #region thumb methods
protected ResizeThumb CreateThumb(PlacementAlignment alignment, Cursor cursor, int index) protected ResizeThumb CreateThumb(PlacementAlignment alignment, Cursor cursor, int index)
{ {
ResizeThumb resizeThumb = new MultiPointResizeThumb { Index = index, Alignment = alignment, Cursor = cursor, IsPrimarySelection = true }; ResizeThumb resizeThumb = new MultiPointResizeThumb { Index = index, Alignment = alignment, Cursor = cursor, IsPrimarySelection = true };
AdornerPlacement ap = Place(ref resizeThumb, alignment, index); AdornerPlacement ap = Place(ref resizeThumb, alignment, index);
(resizeThumb as MultiPointResizeThumb).AdornerPlacement = ap; (resizeThumb as MultiPointResizeThumb).AdornerPlacement = ap;
AdornerPanel.SetPlacement(resizeThumb, ap); AdornerPanel.SetPlacement(resizeThumb, ap);
adornerPanel.Children.Add(resizeThumb); adornerPanel.Children.Add(resizeThumb);
DragListener drag = new DragListener(resizeThumb); DragListener drag = new DragListener(resizeThumb);
WeakEventManager<ResizeThumb, MouseButtonEventArgs>.AddHandler(resizeThumb, "PreviewMouseLeftButtonDown", ResizeThumbOnMouseLeftButtonUp); WeakEventManager<ResizeThumb, MouseButtonEventArgs>.AddHandler(resizeThumb, "PreviewMouseLeftButtonDown", ResizeThumbOnMouseLeftButtonUp);
drag.Started += drag_Started; drag.Started += drag_Started;
drag.Changed += drag_Changed; drag.Changed += drag_Changed;
drag.Completed += drag_Completed; drag.Completed += drag_Completed;
return resizeThumb; return resizeThumb;
} }
private void ResetThumbs() private void ResetThumbs()
{ {
foreach (FrameworkElement rt in adornerPanel.Children) foreach (FrameworkElement rt in adornerPanel.Children)
{ {
if (rt is ResizeThumb) if (rt is ResizeThumb)
(rt as ResizeThumb).IsPrimarySelection = true; (rt as ResizeThumb).IsPrimarySelection = true;
} }
_selectedThumbs.Clear(); _selectedThumbs.Clear();
} }
private void SelectThumb(MultiPointResizeThumb mprt) private void SelectThumb(MultiPointResizeThumb mprt)
{ {
PointCollection points = GetPointCollection(); PointCollection points = GetPointCollection();
Point p = points[mprt.Index]; Point p = points[mprt.Index];
_selectedThumbs.Add(mprt.Index, new Bounds { X = p.X, Y = p.Y }); _selectedThumbs.Add(mprt.Index, new Bounds { X = p.X, Y = p.Y });
mprt.IsPrimarySelection = false; mprt.IsPrimarySelection = false;
} }
#endregion #endregion
#region eventhandlers #region eventhandlers
private void ResizeThumbOnMouseLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs) private void ResizeThumbOnMouseLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{ {
//get current thumb //get current thumb
MultiPointResizeThumb mprt = sender as MultiPointResizeThumb; MultiPointResizeThumb mprt = sender as MultiPointResizeThumb;
if (mprt != null) if (mprt != null)
{ {
//shift+ctrl will remove selected point //shift+ctrl will remove selected point
if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) &&
(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
{ {
//unselect all points //unselect all points
ResetThumbs(); ResetThumbs();
PointCollection points = GetPointCollection(); PointCollection points = GetPointCollection();
//iterate thumbs to lower index of remaining thumbs //iterate thumbs to lower index of remaining thumbs
foreach (MultiPointResizeThumb m in adornerPanel.Children) foreach (MultiPointResizeThumb m in adornerPanel.Children)
{ {
if (m.Index > mprt.Index) if (m.Index > mprt.Index)
m.Index--; m.Index--;
} }
//remove point and thumb //remove point and thumb
points.RemoveAt(mprt.Index); points.RemoveAt(mprt.Index);
adornerPanel.Children.Remove(mprt); adornerPanel.Children.Remove(mprt);
Invalidate(); Invalidate();
} }
else else
{ {
//if not keyboard ctrl is pressed and selected point is not previously selected, clear selection //if not keyboard ctrl is pressed and selected point is not previously selected, clear selection
if (!_selectedThumbs.ContainsKey(mprt.Index) & !Keyboard.IsKeyDown(Key.LeftCtrl) & if (!_selectedThumbs.ContainsKey(mprt.Index) & !Keyboard.IsKeyDown(Key.LeftCtrl) &
!Keyboard.IsKeyDown(Key.RightCtrl)) !Keyboard.IsKeyDown(Key.RightCtrl))
{ {
ResetThumbs(); ResetThumbs();
} }
//add selected thumb, if ctrl pressed this could be all points in poly //add selected thumb, if ctrl pressed this could be all points in poly
if (!_selectedThumbs.ContainsKey(mprt.Index)) if (!_selectedThumbs.ContainsKey(mprt.Index))
SelectThumb(mprt); SelectThumb(mprt);
_isDragging = false; _isDragging = false;
} }
} }
} }
// TODO : Remove all hide/show extensions from here. // TODO : Remove all hide/show extensions from here.
protected void drag_Started(DragListener drag) protected void drag_Started(DragListener drag)
{ {
//get current thumb //get current thumb
MultiPointResizeThumb mprt = (drag.Target as MultiPointResizeThumb); MultiPointResizeThumb mprt = (drag.Target as MultiPointResizeThumb);
if (mprt != null) if (mprt != null)
{ {
SetOperation(); SetOperation();
} }
} }
void SetOperation() void SetOperation()
{ {
var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel; var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel;
if (designPanel != null) _zoom = designPanel.TryFindParent<ZoomControl>();
{
var p = VisualTreeHelper.GetParent(designPanel); if (resizeBehavior != null)
while (p != null && !(p is ZoomControl)) operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize);
{ else
p = VisualTreeHelper.GetParent(p); {
} changeGroup = ExtendedItem.Context.OpenGroup("Resize", extendedItemArray);
_zoom = p as ZoomControl; }
} _isResizing = true;
}
if (resizeBehavior != null)
operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize); void ChangeOperation(PointCollection points)
else {
{ //this is for SharpDevelop built in undo functionality
changeGroup = ExtendedItem.Context.OpenGroup("Resize", extendedItemArray); if (operation != null)
} {
_isResizing = true; var info = operation.PlacedItems[0];
} var result = info.OriginalBounds;
void ChangeOperation(PointCollection points) IEnumerable<double> xs = points.Select(x => x.X);
{ IEnumerable<double> ys = points.Select(y => y.Y);
//this is for SharpDevelop built in undo functionality result.X = (double)(info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance);
if (operation != null) result.Y = (double)(info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance);
{ result.Width = xs.Max() - xs.Min();
var info = operation.PlacedItems[0]; result.Height = ys.Max() - ys.Min();
var result = info.OriginalBounds;
info.Bounds = result.Round();
IEnumerable<double> xs = points.Select(x => x.X); operation.CurrentContainerBehavior.BeforeSetPosition(operation);
IEnumerable<double> ys = points.Select(y => y.Y); operation.CurrentContainerBehavior.SetPosition(info);
result.X = (double)(info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance); }
result.Y = (double)(info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance);
result.Width = xs.Max() - xs.Min(); ResetWidthHeightProperties();
result.Height = ys.Max() - ys.Min();
}
info.Bounds = result.Round();
operation.CurrentContainerBehavior.BeforeSetPosition(operation); void CommitOperation()
operation.CurrentContainerBehavior.SetPosition(info); {
} if (operation != null)
{
ResetWidthHeightProperties(); PointCollection points;
Polygon pg = ExtendedItem.View as Polygon;
} Polyline pl = ExtendedItem.View as Polyline;
if (pl == null)
void CommitOperation() {
{ points = pg.Points;
if (operation != null)
{ }
PointCollection points; else
Polygon pg = ExtendedItem.View as Polygon; {
Polyline pl = ExtendedItem.View as Polyline; points = pl.Points;
if (pl == null) }
{
points = pg.Points; foreach (int i in _selectedThumbs.Keys)
{
} _selectedThumbs[i].X = points[i].X;
else _selectedThumbs[i].Y = points[i].Y;
{ }
points = pl.Points; ExtendedItem.Properties.GetProperty(pl != null ? Polyline.PointsProperty : Polygon.PointsProperty).SetValue(points);
} ResetWidthHeightProperties();
operation.Commit();
foreach (int i in _selectedThumbs.Keys)
{ operation = null;
_selectedThumbs[i].X = points[i].X; }
_selectedThumbs[i].Y = points[i].Y; else
} {
ExtendedItem.Properties.GetProperty(pl != null ? Polyline.PointsProperty : Polygon.PointsProperty).SetValue(points); changeGroup.Commit();
ResetWidthHeightProperties(); changeGroup = null;
operation.Commit(); }
_isResizing = false;
operation = null;
} ResetWidthHeightProperties();
else Invalidate();
{ }
changeGroup.Commit();
changeGroup = null; protected void drag_Changed(DragListener drag)
} {
_isResizing = false; PointCollection points = GetPointCollection();
ResetWidthHeightProperties(); MultiPointResizeThumb mprt = drag.Target as MultiPointResizeThumb;
Invalidate(); if (mprt != null)
} {
double dx = 0;
protected void drag_Changed(DragListener drag) double dy = 0;
{ //if has zoomed
PointCollection points = GetPointCollection(); if (_zoom != null)
{
MultiPointResizeThumb mprt = drag.Target as MultiPointResizeThumb; dx = drag.Delta.X * (1 / _zoom.CurrentZoom);
if (mprt != null) dy = drag.Delta.Y * (1 / _zoom.CurrentZoom);
{ }
double dx = 0;
double dy = 0; Double theta;
//if has zoomed //if one point selected snapping angle is calculated in relation to previous point
if (_zoom != null) if (_selectedThumbs.Count == 1)
{ {
dx = drag.Delta.X * (1 / _zoom.CurrentZoom); theta = (180 / Math.PI) * Math.Atan2(_selectedThumbs[mprt.Index].Y + dy - points[mprt.Index - 1].Y, _selectedThumbs[mprt.Index].X + dx - points[mprt.Index - 1].X);
dy = drag.Delta.Y * (1 / _zoom.CurrentZoom); }
} else//if multiple points snapping angle is calculated in relation to mouse dragging angle
{
Double theta; theta = (180 / Math.PI) * Math.Atan2(dy, dx);
//if one point selected snapping angle is calculated in relation to previous point }
if (_selectedThumbs.Count == 1)
{ //snappingAngle is used for snapping function to horizontal or vertical plane in line drawing, and is activated by pressing ctrl or shift button
theta = (180 / Math.PI) * Math.Atan2(_selectedThumbs[mprt.Index].Y + dy - points[mprt.Index - 1].Y, _selectedThumbs[mprt.Index].X + dx - points[mprt.Index - 1].X); int? snapAngle = null;
}
else//if multiple points snapping angle is calculated in relation to mouse dragging angle //shift+alt gives a new point
{ if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)))
theta = (180 / Math.PI) * Math.Atan2(dy, dx); {
} //if dragging occurs on a point and that point is the only selected, a new node will be added.
//_isCtrlDragging is needed since this method is called for every x pixel that the mouse moves
//snappingAngle is used for snapping function to horizontal or vertical plane in line drawing, and is activated by pressing ctrl or shift button //so it could be many thousands of times during a single dragging
int? snapAngle = null; if (!_isDragging && _selectedThumbs.Count == 1 && (Math.Abs(dx) > 0 || Math.Abs(dy) > 0))
{
//shift+alt gives a new point
if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))) //duplicate point that is selected
{ Point p = points[mprt.Index];
//if dragging occurs on a point and that point is the only selected, a new node will be added.
//_isCtrlDragging is needed since this method is called for every x pixel that the mouse moves //insert duplicate
//so it could be many thousands of times during a single dragging points.Insert(mprt.Index, p);
if (!_isDragging && _selectedThumbs.Count == 1 && (Math.Abs(dx) > 0 || Math.Abs(dy) > 0))
{ //create adorner marker
CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE, mprt.Index);
//duplicate point that is selected
Point p = points[mprt.Index]; //set index of all points that had a higher index than selected to +1
foreach (FrameworkElement rt in adornerPanel.Children)
//insert duplicate {
points.Insert(mprt.Index, p); if (rt is MultiPointResizeThumb)
{
//create adorner marker MultiPointResizeThumb t = rt as MultiPointResizeThumb;
CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE, mprt.Index); if (t.Index > mprt.Index)
t.Index++;
//set index of all points that had a higher index than selected to +1 }
foreach (FrameworkElement rt in adornerPanel.Children) }
{
if (rt is MultiPointResizeThumb) //set index of new point to old point index + 1
{ mprt.Index = mprt.Index + 1;
MultiPointResizeThumb t = rt as MultiPointResizeThumb; ResetThumbs();
if (t.Index > mprt.Index) SelectThumb(mprt);
t.Index++;
} }
} snapAngle = 10;
}
//set index of new point to old point index + 1
mprt.Index = mprt.Index + 1; //snapping occurs when mouse is within 10 degrees from horizontal or vertical plane if shift is pressed
ResetThumbs(); else if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
SelectThumb(mprt); {
snapAngle = 10;
} }
snapAngle = 10; //snapping occurs within 45 degree intervals that is line will always be horizontal or vertical if alt is pressed
} else if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{
//snapping occurs when mouse is within 10 degrees from horizontal or vertical plane if shift is pressed snapAngle = 45;
else if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) }
{ _isDragging = true;
snapAngle = 10; points = MovePoints(points, dx, dy, theta, snapAngle);
}
//snapping occurs within 45 degree intervals that is line will always be horizontal or vertical if alt is pressed }
else if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)) ChangeOperation(points);
{ (drag.Target as ResizeThumb).InvalidateArrange();
snapAngle = 45;
}
_isDragging = true; }
points = MovePoints(points, dx, dy, theta, snapAngle);
protected void drag_Completed(DragListener drag)
} {
ChangeOperation(points); MultiPointResizeThumb mprt = drag.Target as MultiPointResizeThumb;
(drag.Target as ResizeThumb).InvalidateArrange(); if (mprt != null)
{
if (operation != null && drag.IsCanceled)
} {
operation.Abort();
protected void drag_Completed(DragListener drag) }
{ else if (drag.IsCanceled)
MultiPointResizeThumb mprt = drag.Target as MultiPointResizeThumb; {
if (mprt != null) changeGroup.Abort();
{ }
if (operation != null && drag.IsCanceled) CommitOperation();
{ }
operation.Abort(); }
}
else if (drag.IsCanceled)
{
changeGroup.Abort(); protected override void OnInitialized()
} {
CommitOperation(); base.OnInitialized();
}
} PointCollection points = GetPointCollection();
if (ExtendedItem.Properties[Shape.StrokeProperty].ValueOnInstance == null)
{
protected override void OnInitialized() ExtendedItem.Properties[Shape.StrokeProperty].SetValue(Colors.Black);
{ ExtendedItem.Properties[Shape.StrokeThicknessProperty].SetValue(2d);
base.OnInitialized(); ExtendedItem.Properties[Shape.StretchProperty].SetValue(Stretch.None);
points.AddRange(new List<Point> { new Point(0, 0), new Point(20, 20) });
PointCollection points = GetPointCollection(); ExtendedItem.Properties.GetProperty(ExtendedItem.View as Polyline != null ? Polyline.PointsProperty : Polygon.PointsProperty).SetValue(points);
}
if (ExtendedItem.Properties[Shape.StrokeProperty].ValueOnInstance == null)
{ resizeThumbs = new List<ResizeThumb>();
ExtendedItem.Properties[Shape.StrokeProperty].SetValue(Colors.Black); for (int i = 1; i < points.Count; i++)
ExtendedItem.Properties[Shape.StrokeThicknessProperty].SetValue(2d); {
ExtendedItem.Properties[Shape.StretchProperty].SetValue(Stretch.None); CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE, i);
points.AddRange(new List<Point> { new Point(0, 0), new Point(20, 20) }); }
ExtendedItem.Properties.GetProperty(ExtendedItem.View as Polyline != null ? Polyline.PointsProperty : Polygon.PointsProperty).SetValue(points);
} Invalidate();
resizeThumbs = new List<ResizeThumb>(); ResetWidthHeightProperties();
for (int i = 1; i < points.Count; i++)
{ ResetThumbs();
CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE, i); _isDragging = false;
}
extendedItemArray[0] = ExtendedItem;
Invalidate(); ExtendedItem.PropertyChanged += OnPropertyChanged;
Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged;
ResetWidthHeightProperties(); resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray);
UpdateAdornerVisibility();
ResetThumbs(); OnPrimarySelectionChanged(null, null);
_isDragging = false; }
extendedItemArray[0] = ExtendedItem; #endregion
ExtendedItem.PropertyChanged += OnPropertyChanged;
Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged; PointCollection GetPointCollection()
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray); {
UpdateAdornerVisibility(); Polygon pg = ExtendedItem.View as Polygon;
OnPrimarySelectionChanged(null, null); Polyline pl = ExtendedItem.View as Polyline;
}
return pl == null ? pg.Points : pl.Points;
#endregion }
PointCollection GetPointCollection() PointCollection MovePoints(PointCollection pc, double displacementX, double displacementY, double theta, int? snapangle)
{ {
Polygon pg = ExtendedItem.View as Polygon; //iterate all selected points
Polyline pl = ExtendedItem.View as Polyline; foreach (int i in _selectedThumbs.Keys)
{
return pl == null ? pg.Points : pl.Points; Point p = pc[i];
}
//x and y is calculated from the currentl point
PointCollection MovePoints(PointCollection pc, double displacementX, double displacementY, double theta, int? snapangle) double x = _selectedThumbs[i].X + displacementX;
{ double y = _selectedThumbs[i].Y + displacementY;
//iterate all selected points
foreach (int i in _selectedThumbs.Keys) //if snap is applied
{ if (snapangle != null)
Point p = pc[i]; {
if (_selectedThumbs.Count > 0)
//x and y is calculated from the currentl point {
double x = _selectedThumbs[i].X + displacementX; //horizontal snap
double y = _selectedThumbs[i].Y + displacementY; if (Math.Abs(theta) < snapangle || 180 - Math.Abs(theta) < snapangle)
{
//if snap is applied //if one point selected use point before as snap point, else snap to movement
if (snapangle != null) y = _selectedThumbs.Count == 1 ? pc[i - 1].Y : y - displacementY;
{ }
if (_selectedThumbs.Count > 0) else if (Math.Abs(90 - Math.Abs(theta)) < snapangle)//vertical snap
{ {
//horizontal snap //if one point selected use point before as snap point, else snap to movement
if (Math.Abs(theta) < snapangle || 180 - Math.Abs(theta) < snapangle) x = _selectedThumbs.Count == 1 ? pc[i - 1].X : x - displacementX;
{ }
//if one point selected use point before as snap point, else snap to movement }
y = _selectedThumbs.Count == 1 ? pc[i - 1].Y : y - displacementY; }
}
else if (Math.Abs(90 - Math.Abs(theta)) < snapangle)//vertical snap p.X = x;
{ p.Y = y;
//if one point selected use point before as snap point, else snap to movement pc[i] = p;
x = _selectedThumbs.Count == 1 ? pc[i - 1].X : x - displacementX; }
} return pc;
} }
}
#region IKeyDown
p.X = x;
p.Y = y; public bool InvokeDefaultAction
pc[i] = p; {
} get { return _selectedThumbs.Count == 0 || _selectedThumbs.Count == GetPointCollection().Count - 1; }
return pc; }
}
int _movingDistance;
#region IKeyDown public void KeyDownAction(object sender, KeyEventArgs e)
{
public bool InvokeDefaultAction Debug.WriteLine("KeyDown");
{ if (IsArrowKey(e.Key))
get { return _selectedThumbs.Count == 0 || _selectedThumbs.Count == GetPointCollection().Count - 1; } if (operation == null)
} {
SetOperation();
int _movingDistance; _movingDistance = 0;
public void KeyDownAction(object sender, KeyEventArgs e) }
{
Debug.WriteLine("KeyDown");
if (IsArrowKey(e.Key)) var dx1 = (e.Key == Key.Left) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance - 10 : _movingDistance - 1 : 0;
if (operation == null) var dy1 = (e.Key == Key.Up) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance - 10 : _movingDistance - 1 : 0;
{ var dx2 = (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0;
SetOperation(); var dy2 = (e.Key == Key.Down) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0;
_movingDistance = 0;
} ChangeOperation(MovePoints(GetPointCollection(), dx1 + dx2, dy1 + dy2, 0, null));
_movingDistance = (dx1 + dx2 + dy1 + dy2);
}
var dx1 = (e.Key == Key.Left) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance - 10 : _movingDistance - 1 : 0;
var dy1 = (e.Key == Key.Up) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance - 10 : _movingDistance - 1 : 0; public void KeyUpAction(object sender, KeyEventArgs e)
var dx2 = (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0; {
var dy2 = (e.Key == Key.Down) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0; Debug.WriteLine("Keyup");
if (IsArrowKey(e.Key))
ChangeOperation(MovePoints(GetPointCollection(), dx1 + dx2, dy1 + dy2, 0, null)); CommitOperation();
_movingDistance = (dx1 + dx2 + dy1 + dy2); }
}
bool IsArrowKey(Key key)
public void KeyUpAction(object sender, KeyEventArgs e) {
{ return (key == Key.Left || key == Key.Right || key == Key.Up || key == Key.Down);
Debug.WriteLine("Keyup"); }
if (IsArrowKey(e.Key)) #endregion
CommitOperation(); }
}
bool IsArrowKey(Key key)
{
return (key == Key.Left || key == Key.Right || key == Key.Up || key == Key.Down);
}
#endregion
}
} }

11
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs

@ -26,6 +26,7 @@ using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer.Controls; using ICSharpCode.WpfDesign.Designer.Controls;
using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Extensions;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.WpfDesign.Designer.UIExtensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
@ -124,15 +125,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
void drag_Started(DragListener drag) void drag_Started(DragListener drag)
{ {
var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel; var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel;
if (designPanel != null) zoom = designPanel.TryFindParent<ZoomControl>();
{
var p = VisualTreeHelper.GetParent(designPanel);
while (p != null && !(p is ZoomControl))
{
p = VisualTreeHelper.GetParent(p);
}
zoom = p as ZoomControl;
}
/* Abort editing Text if it was editing, because it interferes with the undo stack. */ /* Abort editing Text if it was editing, because it interferes with the undo stack. */
foreach(var extension in this.ExtendedItem.Extensions){ foreach(var extension in this.ExtendedItem.Extensions){

11
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs

@ -140,7 +140,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
} }
foreach (var d in drawLines) { foreach (var d in drawLines) {
DrawLine(d.Start, d.Offset, d.End, d.Offset); DrawLine(d.Start, d.Offset + d.DrawOffset, d.End, d.Offset + d.DrawOffset);
} }
} }
@ -163,7 +163,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
} }
foreach (var d in drawLines) { foreach (var d in drawLines) {
DrawLine(d.Offset, d.Start, d.Offset, d.End); DrawLine(d.Offset + d.DrawOffset, d.Start, d.Offset + d.DrawOffset, d.End);
} }
} }
} }
@ -264,8 +264,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
if (filter == null) if (filter == null)
{ {
h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Top + Math.Abs((r2.Top - r2.Bottom) / 2), Start = r.Left, End = r.Right }); h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Top + Math.Abs((r2.Top - r2.Bottom) / 2) - 1, DrawOffset = 1, Start = r.Left, End = r.Right });
v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left + Math.Abs((r2.Left - r2.Right) / 2), Start = r.Top, End = r.Bottom }); v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left + Math.Abs((r2.Left - r2.Right) / 2) - 1, DrawOffset = 1, Start = r.Top, End = r.Bottom });
} }
} }
} }
@ -365,6 +365,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
drawLine = new Snapline(); drawLine = new Snapline();
drawLine.Start = double.MaxValue; drawLine.Start = double.MaxValue;
drawLine.End = double.MinValue; drawLine.End = double.MinValue;
drawLine.DrawOffset = mapLine.DrawOffset;
offsetDict[offset] = drawLine; offsetDict[offset] = drawLine;
} }
drawLine.Offset = offset; drawLine.Offset = offset;
@ -386,6 +387,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public double End; public double End;
public bool RequireOverlap; public bool RequireOverlap;
public int Group; public int Group;
public double DrawOffset = 0;
} }
} }
} }

142
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DummyValueInsteadOfNullTypeDescriptionProvider.cs

@ -0,0 +1,142 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.ComponentModel;
using System.Linq;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// Description of DummyValueInsteadOfNullTypeDescriptionProvider.
/// </summary>
public sealed class DummyValueInsteadOfNullTypeDescriptionProvider : TypeDescriptionProvider
{
// By using a TypeDescriptionProvider, we can intercept all access to the property that is
// using a PropertyDescriptor. WpfDesign.XamlDom uses a PropertyDescriptor for accessing
// properties (except for attached properties), so even DesignItemProperty/XamlProperty.ValueOnInstance
// will report null when the actual value is the dummy value.
readonly string _propertyName;
readonly object _dummyValue;
public DummyValueInsteadOfNullTypeDescriptionProvider(TypeDescriptionProvider existingProvider,
string propertyName, object dummyValue)
: base(existingProvider)
{
this._propertyName = propertyName;
this._dummyValue = dummyValue;
}
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new ShadowTypeDescriptor(this, base.GetTypeDescriptor(objectType, instance));
}
sealed class ShadowTypeDescriptor : CustomTypeDescriptor
{
readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent;
public ShadowTypeDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent,
ICustomTypeDescriptor existingDescriptor)
: base(existingDescriptor)
{
this._parent = parent;
}
public override PropertyDescriptorCollection GetProperties()
{
return Filter(base.GetProperties());
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return Filter(base.GetProperties(attributes));
}
PropertyDescriptorCollection Filter(PropertyDescriptorCollection properties)
{
PropertyDescriptor property = properties[_parent._propertyName];
if (property != null) {
if ((properties as System.Collections.IDictionary).IsReadOnly) {
properties = new PropertyDescriptorCollection(properties.Cast<PropertyDescriptor>().ToArray());
}
properties.Remove(property);
properties.Add(new ShadowPropertyDescriptor(_parent, property));
}
return properties;
}
}
sealed class ShadowPropertyDescriptor : PropertyDescriptor
{
readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent;
readonly PropertyDescriptor _baseDescriptor;
public ShadowPropertyDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent,
PropertyDescriptor existingDescriptor)
: base(existingDescriptor)
{
this._parent = parent;
this._baseDescriptor = existingDescriptor;
}
public override Type ComponentType {
get { return _baseDescriptor.ComponentType; }
}
public override bool IsReadOnly {
get { return _baseDescriptor.IsReadOnly; }
}
public override Type PropertyType {
get { return _baseDescriptor.PropertyType; }
}
public override bool CanResetValue(object component)
{
return _baseDescriptor.CanResetValue(component);
}
public override object GetValue(object component)
{
object value = _baseDescriptor.GetValue(component);
if (value == _parent._dummyValue)
return null;
else
return value;
}
public override void ResetValue(object component)
{
_baseDescriptor.SetValue(component, _parent._dummyValue);
}
public override void SetValue(object component, object value)
{
_baseDescriptor.SetValue(component, value ?? _parent._dummyValue);
}
public override bool ShouldSerializeValue(object component)
{
return _baseDescriptor.ShouldSerializeValue(component)
&& _baseDescriptor.GetValue(component) != _parent._dummyValue;
}
}
}
}

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

@ -73,6 +73,7 @@
<Compile Include="Adorners\AdornerProvider.cs" /> <Compile Include="Adorners\AdornerProvider.cs" />
<Compile Include="Adorners\AdornerProviderClasses.cs" /> <Compile Include="Adorners\AdornerProviderClasses.cs" />
<Compile Include="Adorners\RelativePlacement.cs" /> <Compile Include="Adorners\RelativePlacement.cs" />
<Compile Include="DummyValueInsteadOfNullTypeDescriptionProvider.cs" />
<Compile Include="ExtensionMethods.cs" /> <Compile Include="ExtensionMethods.cs" />
<Compile Include="Extensions\ExtensionAttribute.cs" /> <Compile Include="Extensions\ExtensionAttribute.cs" />
<Compile Include="Extensions\ExtensionInterfaces.cs" /> <Compile Include="Extensions\ExtensionInterfaces.cs" />

Loading…
Cancel
Save