diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
index 9df9884dcfc..7ef616743d9 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
@@ -4,6 +4,8 @@
using System;
using System.Threading;
using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Markup;
using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.XamlDom;
@@ -14,6 +16,15 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
[TestFixture]
public class EditOperationTests : ModelTestHelper
{
+ protected override XamlLoadSettings CreateXamlLoadSettings()
+ {
+ var settings = base.CreateXamlLoadSettings();
+
+ settings.TypeFinder.RegisterAssembly(typeof(NamespaceTests).Assembly);
+
+ return settings;
+ }
+
Mutex mutex;
[TestFixtureSetUp]
@@ -204,5 +215,108 @@ public void PasteSameElementMultipleTimesCheckCopiesNames()
Assert.IsNotNull(nameScope.FindName(_name + "_Copy3"));
Assert.IsNull(nameScope.FindName(_name + "_Copy4"));
}
+
+ [Test]
+ public void PasteCustomControlUsingMixedTypes()
+ {
+ DesignItem grid = CreateGridContextWithDesignSurface("");
+ DesignItem myButton = grid.Services.Component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.Controls.CustomButton());
+ grid.Properties["Children"].CollectionElements.Add(myButton);
+
+ DesignItem extensionItem = grid.Services.Component.RegisterComponentForDesigner(new MyExtension());
+ extensionItem.Properties["MyProperty1"].SetValue(new Button());
+ myButton.Properties[ICSharpCode.WpfDesign.Tests.Controls.CustomButton.TagProperty].SetValue(extensionItem);
+
+ var xamlContext = grid.Context as XamlDesignContext;
+ Assert.IsNotNull(xamlContext);
+ xamlContext.XamlEditAction.Copy(new[] {myButton});
+
+ grid = CreateGridContextWithDesignSurface("");
+ xamlContext = grid.Context as XamlDesignContext;
+ Assert.IsNotNull(xamlContext);
+ var selection = grid.Services.Selection;
+ selection.SetSelectedComponents(new[] {grid});
+ xamlContext.XamlEditAction.Paste();
+
+ string expectedXaml = "\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "\n";
+
+ AssertGridDesignerOutput(expectedXaml, grid.Context,
+ "xmlns:Controls0=\"clr-namespace:ICSharpCode.WpfDesign.Tests.Designer;assembly=ICSharpCode.WpfDesign.Tests\"",
+ "xmlns:sdtcontrols=\"http://sharpdevelop.net/WpfDesign/Tests/Controls\"");
+ }
+
+ [Test]
+ public void PasteCustomControlUsingStaticResource()
+ {
+ DesignItem grid = CreateGridContextWithDesignSurface("");
+
+ DesignItemProperty resProp = grid.Properties.GetProperty("Resources");
+ Assert.IsTrue(resProp.IsCollection);
+ DesignItem exampleClassItem = grid.Services.Component.RegisterComponentForDesigner(new ExampleClass());
+ exampleClassItem.Key = "res1";
+ resProp.CollectionElements.Add(exampleClassItem);
+
+ DesignItem myButton = grid.Services.Component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.Controls.CustomButton());
+ grid.Properties["Children"].CollectionElements.Add(myButton);
+
+ myButton.Properties[TextBox.TagProperty].SetValue(new StaticResourceExtension());
+ myButton.Properties[TextBox.TagProperty].Value.Properties["ResourceKey"].SetValue("res1");
+
+ // Verify xaml document to be copied
+ string expectedXaml = "\n" +
+ " \n" +
+ "\n" +
+ "\n" +
+ "\n";
+
+ AssertGridDesignerOutput(expectedXaml, grid.Context,
+ "xmlns:Controls0=\"clr-namespace:ICSharpCode.WpfDesign.Tests.Designer;assembly=ICSharpCode.WpfDesign.Tests\"",
+ "xmlns:sdtcontrols=\"http://sharpdevelop.net/WpfDesign/Tests/Controls\"");
+
+ var xamlContext = grid.Context as XamlDesignContext;
+ Assert.IsNotNull(xamlContext);
+ xamlContext.XamlEditAction.Copy(new[] {myButton});
+
+ grid = CreateGridContextWithDesignSurface("");
+
+ resProp = grid.Properties.GetProperty("Resources");
+ Assert.IsTrue(resProp.IsCollection);
+ exampleClassItem = grid.Services.Component.RegisterComponentForDesigner(new ExampleClass());
+ exampleClassItem.Key = "res1";
+ resProp.CollectionElements.Add(exampleClassItem);
+
+ xamlContext = grid.Context as XamlDesignContext;
+ Assert.IsNotNull(xamlContext);
+ var selection = grid.Services.Selection;
+ selection.SetSelectedComponents(new[] {grid});
+ xamlContext.XamlEditAction.Paste();
+
+ AssertGridDesignerOutput(expectedXaml, grid.Context,
+ "xmlns:Controls0=\"clr-namespace:ICSharpCode.WpfDesign.Tests.Designer;assembly=ICSharpCode.WpfDesign.Tests\"",
+ "xmlns:sdtcontrols=\"http://sharpdevelop.net/WpfDesign/Tests/Controls\"");
+ }
+ }
+
+ public class MyExtension : MarkupExtension
+ {
+ public MyExtension()
+ {
+ }
+
+ public override object ProvideValue(IServiceProvider serviceProvider)
+ {
+ return null;
+ }
+
+ public object MyProperty1 { get; set; }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTestHelper.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTestHelper.cs
index 90cef16ea06..c8550fa5fac 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTestHelper.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTestHelper.cs
@@ -30,7 +30,7 @@ public class ModelTestHelper
protected XamlDesignContext CreateContext(string xaml)
{
log = new StringBuilder();
- XamlDesignContext context = new XamlDesignContext(new XmlTextReader(new StringReader(xaml)), new XamlLoadSettings());
+ XamlDesignContext context = new XamlDesignContext(new XmlTextReader(new StringReader(xaml)), CreateXamlLoadSettings());
/*context.Services.Component.ComponentRegistered += delegate(object sender, DesignItemEventArgs e) {
log.AppendLine("Register " + ItemIdentity(e.Item));
};
@@ -78,19 +78,7 @@ protected void AssertCanvasDesignerOutput(string expectedXaml, DesignContext con
expectedXaml.Replace("\r", "").Replace("\n", "\n ")
+ "\n";
- StringWriter stringWriter = new StringWriter();
- XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
- xmlWriter.Formatting = Formatting.Indented;
- context.Save(xmlWriter);
-
- string actualXaml = stringWriter.ToString().Replace("\r", "");;
- if (expectedXaml != actualXaml) {
- Debug.WriteLine("expected xaml:");
- Debug.WriteLine(expectedXaml);
- Debug.WriteLine("actual xaml:");
- Debug.WriteLine(actualXaml);
- }
- Assert.AreEqual(expectedXaml, actualXaml);
+ AssertDesignerOutput(expectedXaml, context);
}
protected DesignItem CreateGridContext(string xaml)
@@ -107,16 +95,51 @@ protected DesignItem CreateGridContextWithDesignSurface(string xaml)
var surface = new DesignSurface();
var xamlWithGrid=@"
" + xaml + "";
- surface.LoadDesigner(new XmlTextReader(new StringReader(xamlWithGrid)), new XamlLoadSettings());
+ surface.LoadDesigner(new XmlTextReader(new StringReader(xamlWithGrid)), CreateXamlLoadSettings());
Assert.IsNotNull(surface.DesignContext.RootItem);
return surface.DesignContext.RootItem;
}
+ protected void AssertGridDesignerOutput(string expectedXaml, DesignContext context, params String[] additionalXmlns)
+ {
+ string gridStartTag = "\n" + expectedXaml.Trim();
+
+ expectedXaml =
+ "\n" +
+ expectedXaml.Replace("\r", "").Replace("\n", "\n ")
+ + "\n";
+
+ AssertDesignerOutput(expectedXaml, context);
+ }
+
static string ItemIdentity(DesignItem item)
{
return item.ComponentType.Name + " (" + item.GetHashCode() + ")";
}
+ protected void AssertDesignerOutput(string expectedXaml, DesignContext context)
+ {
+ StringWriter stringWriter = new StringWriter();
+ XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
+ xmlWriter.Formatting = Formatting.Indented;
+ context.Save(xmlWriter);
+
+ string actualXaml = stringWriter.ToString().Replace("\r", "");;
+ if (expectedXaml != actualXaml) {
+ Debug.WriteLine("expected xaml:");
+ Debug.WriteLine(expectedXaml);
+ Debug.WriteLine("actual xaml:");
+ Debug.WriteLine(actualXaml);
+ }
+ Assert.AreEqual(expectedXaml, actualXaml);
+ }
+
protected void AssertLog(string expectedLog)
{
expectedLog = expectedLog.Replace("\r", "");
@@ -129,5 +152,10 @@ protected void AssertLog(string expectedLog)
}
Assert.AreEqual(expectedLog, actualLog);
}
+
+ protected virtual XamlLoadSettings CreateXamlLoadSettings()
+ {
+ return new XamlLoadSettings();
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
index 77f10e970f8..2c143351880 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
@@ -605,6 +605,39 @@ internal static object CreateObjectFromAttributeText(string valueText, Type targ
scope.OwnerDocument.GetTypeDescriptorContext(scope), valueText);
}
+ ///
+ /// Removes namespace attributes defined in the root from the specified node and all child nodes.
+ ///
+ static void RemoveRootNamespacesFromNodeAndChildNodes(XamlObject root, XmlNode node)
+ {
+ foreach (XmlNode childNode in node.ChildNodes) {
+ RemoveRootNamespacesFromNodeAndChildNodes(root, childNode);
+ }
+
+ if (node.Attributes != null) {
+ List removeAttributes = new List();
+ foreach (XmlAttribute attrib in node.Attributes) {
+ if (attrib.Name.StartsWith("xmlns:")) {
+ var rootPrefix = root.OwnerDocument.GetPrefixForNamespace(attrib.Value);
+ if (rootPrefix == null) {
+ //todo: check if we can add to root, (maybe same ns exists)
+ root.OwnerDocument.XmlDocument.Attributes.Append((XmlAttribute)attrib.CloneNode(true));
+ removeAttributes.Add(attrib);
+ }
+ else if (rootPrefix == attrib.Name.Substring("xmlns:".Length)) {
+ removeAttributes.Add(attrib);
+ }
+ }
+ else if (attrib.Name == "xmlns" && attrib.Value == XamlConstants.PresentationNamespace) {
+ removeAttributes.Add(attrib);
+ }
+ }
+ foreach (var removeAttribute in removeAttributes) {
+ node.Attributes.Remove(removeAttribute);
+ }
+ }
+ }
+
///
/// Method use to parse a piece of Xaml.
///
@@ -625,25 +658,8 @@ public static XamlObject ParseSnippet(XamlObject root, string xaml, XamlParserSe
}
if(xmlnsAttribute!=null)
element.Attributes.Remove(xmlnsAttribute);
-
- //Remove namespace Attributes defined in the Xaml Root from the Pasted Snippet!
- List removeAttributes = new List();
- foreach (XmlAttribute attrib in element.Attributes) {
- if (attrib.Name.StartsWith("xmlns:")) {
- var rootPrefix = root.OwnerDocument.GetPrefixForNamespace(attrib.Value);
- if (rootPrefix == null) {
- //todo: check if we can add to root, (maybe same ns exists)
- root.OwnerDocument.XmlDocument.Attributes.Append((XmlAttribute)attrib.CloneNode(true));
- removeAttributes.Add(attrib);
- } else if (rootPrefix == attrib.Name.Substring(6)) {
- removeAttributes.Add(attrib);
- }
- }
- }
- foreach (var removeAttribute in removeAttributes) {
- element.Attributes.Remove(removeAttribute);
- }
- //end remove
+
+ RemoveRootNamespacesFromNodeAndChildNodes(root, element);
XamlParser parser = new XamlParser();
parser.settings = settings;
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
index 5bdf7ae47d1..b14ba0e5440 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
@@ -57,8 +57,14 @@ public Type Resolve(string typeName)
typeNamespaceUri = GetNamespaceOfPrefix("");
typeLocalName = typeName;
}
- if (string.IsNullOrEmpty(typeNamespaceUri))
+ if (string.IsNullOrEmpty(typeNamespaceUri)) {
+ var documentResolver = this.document.RootElement.ServiceProvider.Resolver;
+ if (documentResolver != null && documentResolver != this) {
+ return documentResolver.Resolve(typeName);
+ }
+
throw new XamlMarkupExtensionParseException("Unrecognized namespace prefix in type " + typeName);
+ }
return document.TypeFinder.GetType(typeNamespaceUri, typeLocalName);
}