From 46aaadc179ddbd58355525bfcabd8da016b4fa4c Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Fri, 7 Nov 2014 22:07:53 +0100 Subject: [PATCH 01/14] Support for {x:Reference} by implementing on method of IXamlNameResolver --- .../Project/XamlObjectServiceProvider.cs | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs index 1b05165a23..3cac378105 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs @@ -29,7 +29,7 @@ namespace ICSharpCode.WpfDesign.XamlDom /// A service provider that provides the IProvideValueTarget and IXamlTypeResolver services. /// No other services (e.g. from the document's service provider) are offered. /// - public class XamlObjectServiceProvider : IServiceProvider, IProvideValueTarget, IXamlSchemaContextProvider, IAmbientProvider + public class XamlObjectServiceProvider : IServiceProvider, IXamlNameResolver, IProvideValueTarget, IXamlSchemaContextProvider, IAmbientProvider { /// /// Creates a new XamlObjectServiceProvider instance. @@ -71,6 +71,11 @@ namespace ICSharpCode.WpfDesign.XamlDom if (serviceType == typeof(IAmbientProvider)) { return this; } + if (serviceType == typeof(IXamlNameResolver)) + { + return this; + } + return null; } @@ -181,5 +186,55 @@ namespace ICSharpCode.WpfDesign.XamlDom } #endregion + + #region IXamlNameResolver + + public object Resolve(string name) + { + INameScope ns = null; + var xamlObj = this.XamlObject; + while (xamlObj != null) + { + ns = NameScopeHelper.GetNameScopeFromObject(xamlObj.Instance); + + if (ns != null) + break; + + xamlObj = xamlObj.ParentObject; + } + + var obj = ns.FindName(name); + + return obj; + } + + public object Resolve(string name, out bool isFullyInitialized) + { + throw new NotImplementedException(); + } + + public object GetFixupToken(IEnumerable names) + { + throw new NotImplementedException(); + } + + public object GetFixupToken(IEnumerable names, bool canAssignDirectly) + { + throw new NotImplementedException(); + } + + public IEnumerable> GetAllNamesAndValuesInScope() + { + throw new NotImplementedException(); + } + + public bool IsFixupTokenAvailable + { + get { throw new NotImplementedException(); } + } + + public event EventHandler OnNameScopeInitializationComplete; + + #endregion } } From d14b6959f7c4f0da93637c86b5ce8190f204a2d4 Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Fri, 7 Nov 2014 22:10:52 +0100 Subject: [PATCH 02/14] Test for {x:Reference} --- .../Tests/XamlDom/SamplesTests.cs | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs index 7cc26d38c8..3f5a51c39f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs @@ -16,7 +16,11 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.IO; +using System.Windows; +using System.Windows.Markup; +using System.Xaml; using ICSharpCode.WpfDesign.XamlDom; using NUnit.Framework; @@ -25,6 +29,32 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom [TestFixture] public class SamplesTests : TestHelper { + /// + /// Non-trivial because of: InlineCollection wrapping a string + /// + [Test] + public void Complex1() + { + TestLoading(@" + + + + + + + Header 1 + Header 2 + Header 3 + +"); + } + /// /// Non-trivial because of: InlineCollection wrapping a string /// @@ -45,7 +75,7 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom "); } - + /// /// Non-trivial because of: found a bug in Control.Content handling /// @@ -345,6 +375,28 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom "); } + + [Test] + public void XReferenceTest1() + { + TestLoading(@" + + + +"); + } + + [Test] + public void Style2() + { + TestLoading(@" + + + +"); + } + + [Test] + [Ignore("Xaml writer creates different XAML")] + public void Style3() + { + TestLoading(@" + + + +"); + } + [Test] public void ListBox1() { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs index 929d58b6b8..76390d7dde 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs @@ -224,7 +224,14 @@ namespace ICSharpCode.WpfDesign.XamlDom { if (PropertyValue != null) { try { - ValueOnInstance = PropertyValue.GetValueFor(propertyInfo); + if (propertyInfo.ReturnType == typeof (FrameworkElementFactory)) + { + ValueOnInstance = TemplateHelper.XamlObjectToFrameworkElementFactory((XamlObject) PropertyValue); + } + else + { + ValueOnInstance = PropertyValue.GetValueFor(propertyInfo); + } if (this.parentObject.XamlSetTypeConverter != null) this.ParentObject.XamlSetTypeConverter(this.parentObject.Instance, new XamlSetTypeConverterEventArgs(this.SystemXamlMemberForProperty, null, ((XamlTextValue) propertyValue).Text, this.parentObject.OwnerDocument.GetTypeDescriptorContext(this.parentObject), null)); From eb932cf5c7c11ea536fdb45de0a77368c6679696 Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Sun, 9 Nov 2014 17:46:54 +0100 Subject: [PATCH 07/14] One more Template Test --- .../Tests/XamlDom/SamplesTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs index 96834e98f3..6dc0487c85 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs @@ -481,6 +481,29 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom "); } + + [Test] + public void Template1() + { + TestLoading(@" + + + +"); + } + [Test] public void ListBox1() From eb86aa7a0f14328f5a68fa37eedff08de73c2fa3 Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Mon, 10 Nov 2014 08:13:45 +0100 Subject: [PATCH 08/14] - Fixes that FrameworkTemplates now complety work - Fixes Problems when Xaml Child Nodes have Whitespace elements - Fixes Type Finder Problems with mscorlib - Fixes on MarkupExtensions Properties are not always of the Object, but are also not attached, so they still should be found --- .../Extensions/EditStyleContextMenu.xaml | 11 +++ .../Extensions/EditStyleContextMenu.xaml.cs | 68 +++++++++++++++++++ .../EditStyleContextMenuExtension.cs | 53 +++++++++++++++ .../Project/Translations.cs | 12 +++- .../Project/WpfDesign.Designer.csproj | 7 ++ .../Project/TemplateHelper.cs | 62 ++++++++--------- .../WpfDesign.XamlDom/Project/XamlObject.cs | 2 + .../WpfDesign.XamlDom/Project/XamlParser.cs | 38 +++++++++-- .../WpfDesign.XamlDom/Project/XamlProperty.cs | 13 +--- .../Project/XamlTypeFinder.cs | 5 ++ .../Project/XamlTypeResolverProvider.cs | 3 +- 11 files changed, 220 insertions(+), 54 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml.cs create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenuExtension.cs diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml new file mode 100644 index 0000000000..961888a0b2 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml.cs new file mode 100644 index 0000000000..f23051132e --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenu.xaml.cs @@ -0,0 +1,68 @@ +// 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.IO; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Markup; +using System.Xml; +using ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.FormatedTextEditor; +using ICSharpCode.WpfDesign.Designer.Xaml; +using ICSharpCode.WpfDesign.XamlDom; + +namespace ICSharpCode.WpfDesign.Designer.Extensions +{ + public partial class EditStyleContextMenu + { + private DesignItem designItem; + + public EditStyleContextMenu(DesignItem designItem) + { + this.designItem = designItem; + + InitializeComponent(); + } + + void Click_EditStyle(object sender, RoutedEventArgs e) + { + var element = designItem.View; + object defaultStyleKey = element.GetValue(FrameworkElement.DefaultStyleKeyProperty); + Style style = Application.Current.TryFindResource(defaultStyleKey) as Style; + + var service = ((XamlComponentService) designItem.Services.Component); + + var ms = new MemoryStream(); + XmlTextWriter writer = new XmlTextWriter(ms, System.Text.Encoding.UTF8); + writer.Formatting = Formatting.Indented; + XamlWriter.Save(style, writer); + + var rootItem = this.designItem.Context.RootItem as XamlDesignItem; + + ms.Position = 0; + var sr = new StreamReader(ms); + var xaml = sr.ReadToEnd(); + + var xamlObject = XamlParser.ParseSnippet(rootItem.XamlObject, xaml, ((XamlDesignContext)this.designItem.Context).ParserSettings); + + var styleDesignItem=service.RegisterXamlComponentRecursive(xamlObject); + designItem.Properties.GetProperty("Resources").CollectionElements.Add(styleDesignItem); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenuExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenuExtension.cs new file mode 100644 index 0000000000..685936eccb --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/EditStyleContextMenuExtension.cs @@ -0,0 +1,53 @@ +// 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.Linq; +using System.Windows.Controls; +using ICSharpCode.WpfDesign.Adorners; +using ICSharpCode.WpfDesign.Extensions; + +namespace ICSharpCode.WpfDesign.Designer.Extensions +{ + [ExtensionServer(typeof (OnlyOneItemSelectedExtensionServer))] + [ExtensionFor(typeof (Control))] + [Extension(Order = 10)] + public class EditStyleContextMenuExtension : PrimarySelectionAdornerProvider + { + DesignPanel panel; + ContextMenu contextMenu; + + protected override void OnInitialized() + { + base.OnInitialized(); + + contextMenu = new EditStyleContextMenu(ExtendedItem); + panel = ExtendedItem.Context.Services.DesignPanel as DesignPanel; + if (panel != null) + panel.AddContextMenu(contextMenu); + } + + protected override void OnRemove() + { + if (panel != null) + panel.RemoveContextMenu(contextMenu); + + base.OnRemove(); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs index 6117d3181c..df5334eceb 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs @@ -77,14 +77,14 @@ namespace ICSharpCode.WpfDesign.Designer return "Wrap in Grid"; } } - + public virtual string WrapInBorder { get { return "Wrap in Border"; } } - public virtual string WrapInViewbox { + public virtual string WrapInViewbox { get { return "Wrap in Viewbox"; } @@ -145,5 +145,13 @@ namespace ICSharpCode.WpfDesign.Designer return "Arrange Bottom"; } } + + public virtual string EditStyle + { + get + { + return "Edit Style"; + } + } } } 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 40aadb1395..441f158e22 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -87,6 +87,9 @@ + + EditStyleContextMenu.xaml + TextBlockRightClickContextMenu.xaml @@ -96,6 +99,7 @@ + @@ -285,6 +289,9 @@ + + Designer + Designer diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/TemplateHelper.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/TemplateHelper.cs index 62119762ff..263659a057 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/TemplateHelper.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/TemplateHelper.cs @@ -17,54 +17,46 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Reflection; using System.Windows; +using System.Windows.Controls; +using System.Windows.Markup; +using System.Xml; +using System.Xml.XPath; namespace ICSharpCode.WpfDesign.XamlDom { public static class TemplateHelper { - public static FrameworkElementFactory XamlObjectToFrameworkElementFactory(XamlObject xamlObject) + public static FrameworkTemplate GetFrameworkTemplate(XmlElement xmlElement) { - var factory = new FrameworkElementFactory(xamlObject.ElementType); - foreach (var prop in xamlObject.Properties) + var nav = xmlElement.CreateNavigator(); + + var ns = new Dictionary(); + while (true) { - if (prop.IsCollection) - { - foreach (var propertyValue in prop.CollectionElements) - { - if (propertyValue is XamlObject && !((XamlObject)propertyValue).IsMarkupExtension) - { - factory.AppendChild(XamlObjectToFrameworkElementFactory((XamlObject)propertyValue)); - } - else if (propertyValue is XamlObject) - { - factory.SetValue(prop.DependencyProperty, ((XamlObject)propertyValue).Instance); - } - else - { - factory.SetValue(prop.DependencyProperty, prop.ValueOnInstance); - } - } - } - else + var nsInScope = nav.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml); + foreach (var ak in nsInScope) { - if (prop.PropertyValue is XamlObject && !((XamlObject)prop.PropertyValue).IsMarkupExtension) - { - factory.AppendChild(XamlObjectToFrameworkElementFactory((XamlObject)prop.PropertyValue)); - } - else if (prop.PropertyValue is XamlObject) - { - factory.SetValue(prop.DependencyProperty, ((XamlObject)prop.PropertyValue).Instance); - } - else - { - factory.SetValue(prop.DependencyProperty, prop.ValueOnInstance); - } + if (!ns.ContainsKey(ak.Key) && ak.Key != "") + ns.Add(ak.Key, ak.Value); } + if (!nav.MoveToParent()) + break; } - return factory; + foreach (var dictentry in ns) + { + xmlElement.SetAttribute("xmlns:" + dictentry.Key, dictentry.Value); + } + + var xaml = xmlElement.OuterXml; + StringReader stringReader = new StringReader(xaml); + XmlReader xmlReader = XmlReader.Create(stringReader); + return (FrameworkTemplate)XamlReader.Load(xmlReader); } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs index 1ff20e9a43..626d6849ee 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs @@ -548,6 +548,8 @@ namespace ICSharpCode.WpfDesign.XamlDom if (wrapper != null) { return wrapper.ProvideValue(); } + if (this.ParentObject.ElementType == typeof (Setter) && this.ElementType == typeof(DynamicResourceExtension)) + return Instance; return (Instance as MarkupExtension).ProvideValue(ServiceProvider); } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs index b43125e912..06f637ddcb 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs @@ -192,6 +192,15 @@ namespace ICSharpCode.WpfDesign.XamlDom XamlObject ParseObject(XmlElement element) { Type elementType = settings.TypeFinder.GetType(element.NamespaceURI, element.LocalName); + + if (typeof (FrameworkTemplate).IsAssignableFrom(elementType)) + { + var xamlObj = new XamlObject(document, element, elementType, TemplateHelper.GetFrameworkTemplate(element)); + xamlObj.ParentObject = currentXamlObject; + return xamlObj; + } + + if (elementType == null) { elementType = settings.TypeFinder.GetType(element.NamespaceURI, element.LocalName + "Extension"); if (elementType == null) { @@ -551,12 +560,27 @@ namespace ICSharpCode.WpfDesign.XamlDom return null; } - internal static XamlPropertyInfo GetPropertyInfo(XamlTypeFinder typeFinder, object elementInstance, Type elementType, string xmlNamespace, string localName) + internal static XamlPropertyInfo GetPropertyInfo(XamlTypeFinder typeFinder, object elementInstance, Type elementType, string xmlNamespace, string localName, bool tryFindAllProperties = false) { string typeName, propertyName; SplitQualifiedIdentifier(localName, out typeName, out propertyName); Type propertyType = FindType(typeFinder, xmlNamespace, typeName); - if (elementType == propertyType || propertyType.IsAssignableFrom(elementType)) { + + //Tries to Find All properties, even if they are not attached (For Setters, Bindings, ...) + if (tryFindAllProperties) + { + XamlPropertyInfo propertyInfo = null; + try + { + propertyInfo = FindProperty(elementInstance, propertyType, propertyName); + } + catch (Exception ex) + { } + if (propertyInfo != null) + return propertyInfo; + } + + if (elementType.IsAssignableFrom(propertyType) || propertyType.IsAssignableFrom(elementType)) { return FindProperty(elementInstance, propertyType, propertyName); } else { // This is an attached property @@ -615,7 +639,8 @@ namespace ICSharpCode.WpfDesign.XamlDom static bool IsElementChildACollectionForProperty(XamlTypeFinder typeFinder, XmlElement element, XamlPropertyInfo propertyInfo) { - return element.ChildNodes.Count == 1 && propertyInfo.ReturnType.IsAssignableFrom(FindType(typeFinder, element.FirstChild.NamespaceURI, element.FirstChild.LocalName)); + var nodes = element.ChildNodes.Cast().Where(x => !(x is XmlWhitespace)).ToList(); + return nodes.Count == 1 && propertyInfo.ReturnType.IsAssignableFrom(FindType(typeFinder, nodes[0].NamespaceURI, nodes[0].LocalName)); } void ParseObjectChildElementAsPropertyElement(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty) @@ -645,7 +670,7 @@ namespace ICSharpCode.WpfDesign.XamlDom isElementChildACollectionForProperty = IsElementChildACollectionForProperty(settings.TypeFinder, element, propertyInfo); if (isElementChildACollectionForProperty) - collectionProperty.ParserSetPropertyElement((XmlElement)element.FirstChild); + collectionProperty.ParserSetPropertyElement((XmlElement)element.ChildNodes.Cast().Where(x => !(x is XmlWhitespace)).First()); else { collectionInstance = collectionProperty.propertyInfo.GetValue(obj.Instance); collectionProperty.ParserSetPropertyElement(element); @@ -756,13 +781,14 @@ namespace ICSharpCode.WpfDesign.XamlDom if(xmlnsAttribute!=null) element.Attributes.Remove(xmlnsAttribute); - RemoveRootNamespacesFromNodeAndChildNodes(root, element); - XamlParser parser = new XamlParser(); parser.settings = settings; parser.errorSink = (IXamlErrorSink)settings.ServiceProvider.GetService(typeof(IXamlErrorSink)); parser.document = root.OwnerDocument; var xamlObject = parser.ParseObject(element as XmlElement); + + RemoveRootNamespacesFromNodeAndChildNodes(root, element); + if (xamlObject != null) return xamlObject; } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs index 76390d7dde..3c5cab4bce 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs @@ -224,15 +224,8 @@ namespace ICSharpCode.WpfDesign.XamlDom { if (PropertyValue != null) { try { - if (propertyInfo.ReturnType == typeof (FrameworkElementFactory)) - { - ValueOnInstance = TemplateHelper.XamlObjectToFrameworkElementFactory((XamlObject) PropertyValue); - } - else - { - ValueOnInstance = PropertyValue.GetValueFor(propertyInfo); - } - + ValueOnInstance = PropertyValue.GetValueFor(propertyInfo); + if (this.parentObject.XamlSetTypeConverter != null) this.ParentObject.XamlSetTypeConverter(this.parentObject.Instance, new XamlSetTypeConverterEventArgs(this.SystemXamlMemberForProperty, null, ((XamlTextValue) propertyValue).Text, this.parentObject.OwnerDocument.GetTypeDescriptorContext(this.parentObject), null)); @@ -416,7 +409,7 @@ namespace ICSharpCode.WpfDesign.XamlDom parentObject.XmlElement.AppendChild(parentNode); } - else if (parentNode.ChildNodes.Count > 0) + else if (parentNode.ChildNodes.Cast().Where(x => !(x is XmlWhitespace)).Count() > 0) throw new XamlLoadException("Collection property node must have no children when adding collection element."); parentNode.AppendChild(newChildNode); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs index b072c0ccbc..7d341859c8 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs @@ -162,7 +162,12 @@ namespace ICSharpCode.WpfDesign.XamlDom assembly = name.Substring("assembly=".Length); } XamlNamespace ns = new XamlNamespace(null, xmlNamespace); + Assembly asm = LoadAssembly(assembly); + + if (asm == null && assembly == "mscorlib") + asm = typeof (Boolean).Assembly; + if (asm != null) { AddMappingToNamespace(ns, new AssemblyNamespaceMapping(asm, namespaceName)); } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs index e4ddc91f56..a58ca56b23 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs @@ -111,7 +111,8 @@ namespace ICSharpCode.WpfDesign.XamlDom obj = obj.ParentObject; } if (propertyName.Contains(".")) { - return XamlParser.GetPropertyInfo(document.TypeFinder, null, elementType, propertyNamespace, propertyName); + var allPropertiesAllowed = this.containingObject is XamlObject && (((XamlObject)this.containingObject).ElementType == typeof(Setter) || ((XamlObject)this.containingObject).IsMarkupExtension); + return XamlParser.GetPropertyInfo(document.TypeFinder, null, elementType, propertyNamespace, propertyName, allPropertiesAllowed); } else if (elementType != null) { return XamlParser.FindProperty(null, elementType, propertyName); } else { From 9bb1062dc8d04d7a0c11f6adfbbfb5b8a6813a72 Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Mon, 10 Nov 2014 20:36:08 +0100 Subject: [PATCH 09/14] A few Unit-tests for INamescope (more to follow...) --- .../WpfDesign.Designer/Project/ModelTools.cs | 214 +++++++++--------- .../WpfDesign.Designer/Project/UIHelpers.cs | 4 +- .../Tests/WpfDesign.Tests.csproj | 9 + .../Tests/XamlDom/ExampleControl.cs | 23 ++ .../Tests/XamlDom/NamescopeTest.cs | 132 +++++++++++ .../XamlDom/NamscopeTestUsercontrol.xaml | 13 ++ .../XamlDom/NamscopeTestUsercontrol.xaml.cs | 28 +++ 7 files changed, 314 insertions(+), 109 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/ExampleControl.cs create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamscopeTestUsercontrol.xaml create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamscopeTestUsercontrol.xaml.cs diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs index d37f0845df..b7099f6144 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs @@ -119,7 +119,7 @@ namespace ICSharpCode.WpfDesign.Designer } } - internal static void CreateVisualTree(this UIElement element) + public static void CreateVisualTree(this UIElement element) { try { @@ -227,13 +227,13 @@ namespace ICSharpCode.WpfDesign.Designer { var itemPos = new ItemPos() {DesignItem = designItem}; - var pos = operation.CurrentContainerBehavior.GetPosition(operation, designItem); + var pos = operation.CurrentContainerBehavior.GetPosition(operation, designItem); itemPos.Xmin = pos.X; itemPos.Xmax = pos.X + pos.Width; itemPos.Ymin = pos.Y; itemPos.Ymax = pos.Y + pos.Height; - return itemPos; + return itemPos; } public static void WrapItemsNewContainer(IEnumerable items, Type containerType) @@ -252,7 +252,7 @@ namespace ICSharpCode.WpfDesign.Designer if (placement == null) return; - var operation = PlacementOperation.Start(items.ToList(), PlacementType.Move); + var operation = PlacementOperation.Start(items.ToList(), PlacementType.Move); var newInstance = Activator.CreateInstance(containerType); DesignItem newPanel = _context.Services.Component.RegisterComponentForDesigner(newInstance); @@ -261,7 +261,7 @@ namespace ICSharpCode.WpfDesign.Designer List itemList = new List(); foreach (var item in collection) { - itemList.Add(GetItemPos(operation, item)); + itemList.Add(GetItemPos(operation, item)); //var pos = placement.GetPosition(null, item); if (container.Component is Canvas) { item.Properties.GetAttachedProperty(Canvas.RightProperty).Reset(); @@ -297,7 +297,7 @@ namespace ICSharpCode.WpfDesign.Designer item.DesignItem.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(item.Ymin - ymin); } - newPanel.ContentProperty.CollectionElements.Add(item.DesignItem); + newPanel.ContentProperty.CollectionElements.Add(item.DesignItem); } else if (newPanel.Component is Grid) { Thickness thickness = new Thickness(0); @@ -319,21 +319,21 @@ namespace ICSharpCode.WpfDesign.Designer item.DesignItem.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(thickness); - newPanel.ContentProperty.CollectionElements.Add(item.DesignItem); + newPanel.ContentProperty.CollectionElements.Add(item.DesignItem); } else if (newPanel.Component is Viewbox) { - newPanel.ContentProperty.SetValue(item.DesignItem); + newPanel.ContentProperty.SetValue(item.DesignItem); } } - PlacementOperation operation2 = PlacementOperation.TryStartInsertNewComponents( + PlacementOperation operation2 = PlacementOperation.TryStartInsertNewComponents( container, new[] { newPanel }, new[] { new Rect(xmin, ymin, xmax - xmin, ymax - ymin).Round() }, PlacementType.AddItem ); - operation2.Commit(); + operation2.Commit(); operation.Commit(); @@ -355,8 +355,8 @@ namespace ICSharpCode.WpfDesign.Designer if (placement == null) return; - var operation = PlacementOperation.Start(items.ToList(), PlacementType.Move); - + var operation = PlacementOperation.Start(items.ToList(), PlacementType.Move); + //var changeGroup = container.OpenGroup("Arrange Elements"); List itemList = new List(); @@ -392,19 +392,19 @@ namespace ICSharpCode.WpfDesign.Designer } else if (container.Component is Grid) { - if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance != HorizontalAlignment.Right) - { - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Left = xmin; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } - else - { - var pos = (double)((Panel)item.Parent.Component).ActualWidth - (xmin + (double)((FrameworkElement)item.Component).ActualWidth); - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Right = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } + if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance != HorizontalAlignment.Right) + { + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Left = xmin; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } + else + { + var pos = (double)((Panel)item.Parent.Component).ActualWidth - (xmin + (double)((FrameworkElement)item.Component).ActualWidth); + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Right = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } } } break; @@ -414,34 +414,34 @@ namespace ICSharpCode.WpfDesign.Designer { if (!item.Properties.GetAttachedProperty(Canvas.RightProperty).IsSet) { - if (!item.Properties.GetAttachedProperty(Canvas.RightProperty).IsSet) - { - item.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(mpos - (((FrameworkElement)item.Component).ActualWidth) / 2); - } - else - { - var pp = mpos - (((FrameworkElement)item.Component).ActualWidth) / 2; - var pos = (double)((Panel)item.Parent.Component).ActualWidth - pp - (((FrameworkElement)item.Component).ActualWidth); - item.Properties.GetAttachedProperty(Canvas.RightProperty).SetValue(pos); - } - } + if (!item.Properties.GetAttachedProperty(Canvas.RightProperty).IsSet) + { + item.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(mpos - (((FrameworkElement)item.Component).ActualWidth) / 2); + } + else + { + var pp = mpos - (((FrameworkElement)item.Component).ActualWidth) / 2; + var pos = (double)((Panel)item.Parent.Component).ActualWidth - pp - (((FrameworkElement)item.Component).ActualWidth); + item.Properties.GetAttachedProperty(Canvas.RightProperty).SetValue(pos); + } + } } else if (container.Component is Grid) { - if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance != HorizontalAlignment.Right) - { - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Left = mpos - (((FrameworkElement)item.Component).ActualWidth) / 2; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } - else - { - var pp = mpos - (((FrameworkElement)item.Component).ActualWidth) / 2; - var pos = (double)((Panel)item.Parent.Component).ActualWidth - pp - (((FrameworkElement)item.Component).ActualWidth); - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Right = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } + if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance != HorizontalAlignment.Right) + { + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Left = mpos - (((FrameworkElement)item.Component).ActualWidth) / 2; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } + else + { + var pp = mpos - (((FrameworkElement)item.Component).ActualWidth) / 2; + var pos = (double)((Panel)item.Parent.Component).ActualWidth - pp - (((FrameworkElement)item.Component).ActualWidth); + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Right = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } } } break; @@ -462,20 +462,20 @@ namespace ICSharpCode.WpfDesign.Designer } else if (container.Component is Grid) { - if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance != HorizontalAlignment.Right) - { - var pos = xmax - (double)((FrameworkElement)item.Component).ActualWidth; - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Left = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } - else - { - var pos = (double)((Panel)item.Parent.Component).ActualWidth - xmax; - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Right = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } + if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance != HorizontalAlignment.Right) + { + var pos = xmax - (double)((FrameworkElement)item.Component).ActualWidth; + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Left = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } + else + { + var pos = (double)((Panel)item.Parent.Component).ActualWidth - xmax; + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Right = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } } } break; @@ -495,20 +495,20 @@ namespace ICSharpCode.WpfDesign.Designer } else if (container.Component is Grid) { - if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance != VerticalAlignment.Bottom) - { - item.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(ymin); - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Top = ymin; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } - else - { - var pos = (double)((Panel)item.Parent.Component).ActualHeight - (ymin + (double)((FrameworkElement)item.Component).ActualHeight); - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Bottom = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } + if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance != VerticalAlignment.Bottom) + { + item.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(ymin); + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Top = ymin; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } + else + { + var pos = (double)((Panel)item.Parent.Component).ActualHeight - (ymin + (double)((FrameworkElement)item.Component).ActualHeight); + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Bottom = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } } } break; @@ -529,20 +529,20 @@ namespace ICSharpCode.WpfDesign.Designer } else if (container.Component is Grid) { - if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance != VerticalAlignment.Bottom) - { - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Top = ympos - (((FrameworkElement)item.Component).ActualHeight) / 2; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } - else - { - var pp = mpos - (((FrameworkElement)item.Component).ActualHeight) / 2; - var pos = (double)((Panel)item.Parent.Component).ActualHeight - pp - (((FrameworkElement)item.Component).ActualHeight); - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Bottom = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } + if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance != VerticalAlignment.Bottom) + { + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Top = ympos - (((FrameworkElement)item.Component).ActualHeight) / 2; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } + else + { + var pp = mpos - (((FrameworkElement)item.Component).ActualHeight) / 2; + var pos = (double)((Panel)item.Parent.Component).ActualHeight - pp - (((FrameworkElement)item.Component).ActualHeight); + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Bottom = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } } } break; @@ -563,27 +563,27 @@ namespace ICSharpCode.WpfDesign.Designer } else if (container.Component is Grid) { - if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance != VerticalAlignment.Bottom) - { - var pos = ymax - (double)((FrameworkElement)item.Component).ActualHeight; - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Top = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } - else - { - var pos = (double)((Panel)item.Parent.Component).ActualHeight - ymax; - var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; - margin.Bottom = pos; - item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); - } + if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance != VerticalAlignment.Bottom) + { + var pos = ymax - (double)((FrameworkElement)item.Component).ActualHeight; + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Top = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } + else + { + var pos = (double)((Panel)item.Parent.Component).ActualHeight - ymax; + var margin = (Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance; + margin.Bottom = pos; + item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin); + } } } break; } } - operation.Commit(); + operation.Commit(); } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIHelpers.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIHelpers.cs index 53c6d19d3d..3d7452f045 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIHelpers.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIHelpers.cs @@ -25,7 +25,7 @@ using System.Windows.Media; namespace ICSharpCode.WpfDesign.Designer { - static class UIHelpers + public static class UIHelpers { public static DependencyObject GetParentObject(this DependencyObject child) { @@ -85,7 +85,7 @@ namespace ICSharpCode.WpfDesign.Designer return null; } - public static T TryFindChild(DependencyObject parent, string childName) where T : DependencyObject + public static T TryFindChild(this DependencyObject parent, string childName) where T : DependencyObject { if (parent == null) return null; T foundChild = null; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj index 780ad08b4f..a18897b374 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj @@ -75,8 +75,13 @@ + + + + NamscopeTestUsercontrol.xaml + @@ -106,5 +111,9 @@ Designer + + Designer + MSBuild:Compile + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/ExampleControl.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/ExampleControl.cs new file mode 100644 index 0000000000..7a1822a432 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/ExampleControl.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace ICSharpCode.WpfDesign.Tests.XamlDom +{ + public class ExampleControl : Control + { + public object Property1 + { + get { return (object)GetValue(Property1Property); } + set { SetValue(Property1Property, value); } + } + + public static readonly DependencyProperty Property1Property = + DependencyProperty.Register("Property1", typeof(object), typeof(ExampleControl), new PropertyMetadata(null)); + + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs new file mode 100644 index 0000000000..8af32b28f7 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Markup; +using System.Xml; +using ICSharpCode.WpfDesign.XamlDom; +using NUnit.Framework; +using ICSharpCode.WpfDesign.Designer; + +namespace ICSharpCode.WpfDesign.Tests.XamlDom +{ + [TestFixture] + public class NamescopeTest : TestHelper + { + /// + /// NamescopeTest 1 + /// + [Test] + public void NamescopeTest1() + { + var xaml= @" + + + /// The object to get the XAML namescope for. /// A XAML namescope, as an instance. - public static INameScope GetNameScopeFromObject(object obj) + public static INameScope GetNameScopeFromObject(XamlObject obj) { - var nameScope = obj as INameScope; - if (nameScope == null) { - var depObj = obj as DependencyObject; - if (depObj != null) - nameScope = NameScope.GetNameScope(depObj); + INameScope nameScope = null; + + while (obj != null) + { + nameScope = obj.Instance as INameScope; + if (nameScope == null) + { + var xamlObj = obj.ParentObject != null ? obj.ParentObject : obj; + var depObj = xamlObj.Instance as DependencyObject; + if (depObj != null) + nameScope = NameScope.GetNameScope(depObj); + + if (nameScope != null) + break; + } + + obj = obj.ParentObject; } - + return nameScope; } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs index 7d06a90ae6..0afa53096f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObjectServiceProvider.cs @@ -195,7 +195,7 @@ namespace ICSharpCode.WpfDesign.XamlDom var xamlObj = this.XamlObject; while (xamlObj != null) { - ns = NameScopeHelper.GetNameScopeFromObject(xamlObj.Instance); + ns = NameScopeHelper.GetNameScopeFromObject(xamlObj); if (ns != null) { var obj = ns.FindName(name); From b5c1db0392ceb2e2af8d87ccdfb13b23c3e46885 Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Tue, 11 Nov 2014 22:35:59 +0100 Subject: [PATCH 11/14] Fixes #595 --- .../WpfDesign/WpfDesign/Project/PlacementOperation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs index c878a4f605..dcd1080fbf 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs @@ -218,7 +218,7 @@ namespace ICSharpCode.WpfDesign if (element is FrameworkElement && size.Width < ((FrameworkElement)element).MinWidth) size.Width = ((FrameworkElement)element).MinWidth; if (element is FrameworkElement && size.Height < ((FrameworkElement)element).MinHeight) - size.Height = ((FrameworkElement)element).Height; + size.Height = ((FrameworkElement)element).MinHeight; return size; } From d53b6553a9d682d209389f4bbbffab781ad3a1ae Mon Sep 17 00:00:00 2001 From: jkuehner Date: Wed, 12 Nov 2014 09:20:30 +0100 Subject: [PATCH 12/14] Bugfix: Fixes Problems that many other Projects define the UIHelpers also. So move them to an extra Namespace --- .../WpfDesign.Designer/Project/Controls/ContainerDragHandle.cs | 1 + .../WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs | 1 + .../WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs | 1 + .../WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs | 1 + .../Project/Extensions/TextBlockRightClickContextMenu.xaml.cs | 1 + .../WpfDesign.Designer/Project/OutlineView/OutlineTreeView.cs | 1 + .../Editors/FormatedTextEditor/FormatedTextEditor.xaml.cs | 1 + .../WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs | 1 + .../WpfDesign.Designer/Project/{ => UIExtensions}/UIHelpers.cs | 2 +- .../WpfDesign.Designer/Project/WpfDesign.Designer.csproj | 2 +- .../WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs | 1 + 11 files changed, 11 insertions(+), 2 deletions(-) rename src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/{ => UIExtensions}/UIHelpers.cs (98%) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ContainerDragHandle.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ContainerDragHandle.cs index 27942f1e80..283596a2c5 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ContainerDragHandle.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ContainerDragHandle.cs @@ -27,6 +27,7 @@ using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Designer.Converters; using System.Globalization; using System.Windows.Data; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.Controls { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs index 3958c4e123..5b053c6366 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs @@ -28,6 +28,7 @@ using System.Windows.Media; using ICSharpCode.WpfDesign.Designer.Converters; using System.Globalization; using System.Windows.Data; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.Controls { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs index 5e8bf3d274..2e24bf0a42 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/QuickOperationMenu.cs @@ -25,6 +25,7 @@ using System.Windows.Media; using ICSharpCode.WpfDesign.Designer.Converters; using System.Globalization; using System.Windows.Data; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.Controls diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs index 65066ce356..47c48c1434 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs @@ -27,6 +27,7 @@ using ICSharpCode.WpfDesign.Adorners; using ICSharpCode.WpfDesign.Designer.Controls; using ICSharpCode.WpfDesign.Extensions; using System.Collections.Generic; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.Extensions { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TextBlockRightClickContextMenu.xaml.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TextBlockRightClickContextMenu.xaml.cs index b581d15fe6..262fd14e57 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TextBlockRightClickContextMenu.xaml.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TextBlockRightClickContextMenu.xaml.cs @@ -20,6 +20,7 @@ using System; using System.Linq; using System.Windows; using ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.FormatedTextEditor; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.Extensions { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/OutlineTreeView.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/OutlineTreeView.cs index 30d9a974b5..b15cb23b81 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/OutlineTreeView.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/OutlineTreeView.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.OutlineView { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/FormatedTextEditor/FormatedTextEditor.xaml.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/FormatedTextEditor/FormatedTextEditor.xaml.cs index 720bd79d8d..6cff46e6a1 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/FormatedTextEditor/FormatedTextEditor.xaml.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/FormatedTextEditor/FormatedTextEditor.xaml.cs @@ -23,6 +23,7 @@ using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; using ICSharpCode.WpfDesign.Designer.Xaml; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.FormatedTextEditor { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs index 2913fa6bdc..606ae58684 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs @@ -27,6 +27,7 @@ using System.Windows.Controls.Primitives; using System.Windows.Media; using System.Diagnostics; using ICSharpCode.WpfDesign.Designer.Controls; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Designer.ThumbnailView { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIHelpers.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIExtensions/UIHelpers.cs similarity index 98% rename from src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIHelpers.cs rename to src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIExtensions/UIHelpers.cs index 3d7452f045..23f8b8f152 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIHelpers.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/UIExtensions/UIHelpers.cs @@ -23,7 +23,7 @@ using System.Text; using System.Windows; using System.Windows.Media; -namespace ICSharpCode.WpfDesign.Designer +namespace ICSharpCode.WpfDesign.Designer.UIExtensions { public static class UIHelpers { 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 441f158e22..f3b0cc3433 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -277,7 +277,7 @@ - + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs index 8af32b28f7..09d1357a93 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/NamescopeTest.cs @@ -11,6 +11,7 @@ using System.Xml; using ICSharpCode.WpfDesign.XamlDom; using NUnit.Framework; using ICSharpCode.WpfDesign.Designer; +using ICSharpCode.WpfDesign.Designer.UIExtensions; namespace ICSharpCode.WpfDesign.Tests.XamlDom { From 175f95ebcd59885285b1181b76a4602db9d60e6e Mon Sep 17 00:00:00 2001 From: jkuehner Date: Wed, 12 Nov 2014 09:32:14 +0100 Subject: [PATCH 13/14] Fix Problems with Namescopes --- .../Project/Xaml/XamlModelCollectionElementsCollection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs index 05ac5433e7..d3b1b163cf 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs @@ -175,13 +175,13 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml void RemoveInternal(int index, XamlDesignItem item) { + NameScopeHelper.NameChanged(item.XamlObject, item.Name, null); + Debug.Assert(property.CollectionElements[index] == item.XamlObject); property.CollectionElements.RemoveAt(index); if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index)); - - NameScopeHelper.NameChanged(item.XamlObject, item.Name, null); } void InsertInternal(int index, XamlDesignItem item) From a8bb55539522445a2e0fa923595ba078f4334b6b Mon Sep 17 00:00:00 2001 From: jkuehner Date: Wed, 12 Nov 2014 09:56:37 +0100 Subject: [PATCH 14/14] Posibility to Disable Snaplines via AttachedProperty --- .../Extensions/SnaplinePlacementBehavior.cs | 93 ++++++++++--------- 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs index a4ac2e5fb2..b8cb90fd95 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs @@ -19,16 +19,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows; -using ICSharpCode.WpfDesign.Extensions; -using System.ComponentModel; using ICSharpCode.WpfDesign.Adorners; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; -using System.Windows.Automation.Peers; -using System.Windows.Controls.Primitives; using System.Diagnostics; using System.Windows.Input; @@ -36,6 +31,20 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions { public class SnaplinePlacementBehavior : RasterPlacementBehavior { + public static bool GetDisableSnaplines(DependencyObject obj) + { + return (bool)obj.GetValue(DisableSnaplinesProperty); + } + + public static void SetDisableSnaplines(DependencyObject obj, bool value) + { + obj.SetValue(DisableSnaplinesProperty, value); + } + + public static readonly DependencyProperty DisableSnaplinesProperty = + DependencyProperty.RegisterAttached("DisableSnaplines", typeof(bool), typeof(SnaplinePlacementBehavior), new PropertyMetadata(false)); + + AdornerPanel adornerPanel; Canvas surface; List horizontalMap; @@ -194,18 +203,18 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions if (designItem != null && designItem.ContentProperty != null && designItem.ContentProperty.IsCollection) foreach (var collectionElement in designItem.ContentProperty.CollectionElements) + { + if (collectionElement != null) + yield return collectionElement; + + foreach (var el in AllDesignItems(collectionElement)) { - if (collectionElement != null) - yield return collectionElement; - - foreach (var el in AllDesignItems(collectionElement)) - { - if (el != null) - yield return el; - } + if (el != null) + yield return el; } + } } - + void BuildMaps(PlacementOperation operation) { horizontalMap = new List(); @@ -217,10 +226,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions AddLines(containerRect, 0, false); foreach (var item in AllDesignItems() /* ExtendedItem.ContentProperty.CollectionElements */ - .Except(operation.PlacedItems.Select(f => f.Item))) { + .Except(operation.PlacedItems.Select(f => f.Item)) + .Where(x=>!GetDisableSnaplines(x.View))) { if (item != null) { var bounds = GetPosition(operation, item); - + AddLines(bounds, 0, false); AddLines(bounds, Margin, true); AddBaseline(item, bounds, horizontalMap); @@ -235,26 +245,26 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions void AddLines(Rect r, double inflate, bool requireOverlap, List h, List v, PlacementAlignment? filter) { - if (r != Rect.Empty) - { - Rect r2 = r; - r2.Inflate(inflate, inflate); - - if (filter == null || filter.Value.Vertical == VerticalAlignment.Top) - h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Top - 1, Start = r.Left, End = r.Right }); - if (filter == null || filter.Value.Vertical == VerticalAlignment.Bottom) - h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Bottom - 1, Start = r.Left, End = r.Right }); - if (filter == null || filter.Value.Horizontal == HorizontalAlignment.Left) - v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left - 1, Start = r.Top, End = r.Bottom }); - if (filter == null || filter.Value.Horizontal == HorizontalAlignment.Right) - v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Right - 1, Start = r.Top, End = r.Bottom }); - - 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 }); - v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left + Math.Abs((r2.Left - r2.Right) / 2), Start = r.Top, End = r.Bottom }); - } - } + if (r != Rect.Empty) + { + Rect r2 = r; + r2.Inflate(inflate, inflate); + + if (filter == null || filter.Value.Vertical == VerticalAlignment.Top) + h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Top - 1, Start = r.Left, End = r.Right }); + if (filter == null || filter.Value.Vertical == VerticalAlignment.Bottom) + h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Bottom - 1, Start = r.Left, End = r.Right }); + if (filter == null || filter.Value.Horizontal == HorizontalAlignment.Left) + v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left - 1, Start = r.Top, End = r.Bottom }); + if (filter == null || filter.Value.Horizontal == HorizontalAlignment.Right) + v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Right - 1, Start = r.Top, End = r.Bottom }); + + 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 }); + v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left + Math.Abs((r2.Left - r2.Right) / 2), Start = r.Top, End = r.Bottom }); + } + } } void AddBaseline(DesignItem item, Rect bounds, List list) @@ -279,9 +289,9 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions void DrawLine(double x1, double y1, double x2, double y2) { - if (double.IsInfinity(x1) || double.IsNaN(x1) || double.IsInfinity(y1) || double.IsNaN(y1) || - double.IsInfinity(x2) || double.IsNaN(x2) || double.IsInfinity(y2) || double.IsNaN(y2)) - return; + if (double.IsInfinity(x1) || double.IsNaN(x1) || double.IsInfinity(y1) || double.IsNaN(y1) || + double.IsInfinity(x2) || double.IsNaN(x2) || double.IsInfinity(y2) || double.IsNaN(y2)) + return; var line1 = new Line() { X1 = x1, @@ -321,7 +331,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } static bool Snap(List input, List map, double accuracy, - out List drawLines, out double delta) + out List drawLines, out double delta) { delta = double.MaxValue; drawLines = null; @@ -330,7 +340,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions foreach (var mapLine in map) { if (Math.Abs(mapLine.Offset - inputLine.Offset) <= accuracy) { if (!inputLine.RequireOverlap && !mapLine.RequireOverlap || - Math.Max(inputLine.Start, mapLine.Start) < Math.Min(inputLine.End, mapLine.End)) + Math.Max(inputLine.Start, mapLine.Start) < Math.Min(inputLine.End, mapLine.End)) { if (mapLine.Group == inputLine.Group) delta = mapLine.Offset - inputLine.Offset; @@ -376,4 +386,3 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } } - \ No newline at end of file