From eb86aa7a0f14328f5a68fa37eedff08de73c2fa3 Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Mon, 10 Nov 2014 08:13:45 +0100 Subject: [PATCH] - 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 {