Browse Source

XML-namespaces for controls outside the default XML-namespace is now declared in the document root.

As prefix for the XML-namespaces it primarily uses the value from XmlnsPrefixAttribute if it exists for the XML-namespace, otherwise a "ControlsX" name is generated, where X is the first free value.
pull/53/merge
Tobias Gummesson 12 years ago committed by Siegfried Pammer
parent
commit
e3a032913f
  1. 56
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
  2. 48
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs

56
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs

@ -17,7 +17,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlObject _rootElement; XamlObject _rootElement;
IServiceProvider _serviceProvider; IServiceProvider _serviceProvider;
XamlTypeFinder _typeFinder; XamlTypeFinder _typeFinder;
int namespacePrefixCounter;
internal XmlDocument XmlDocument { internal XmlDocument XmlDocument {
get { return _xmlDoc; } get { return _xmlDoc; }
@ -164,11 +166,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
bool hasStringConverter = c.CanConvertTo(ctx, typeof(string)) && c.CanConvertFrom(typeof(string)); bool hasStringConverter = c.CanConvertTo(ctx, typeof(string)) && c.CanConvertFrom(typeof(string));
if (forProperty != null && hasStringConverter) { if (forProperty != null && hasStringConverter) {
return new XamlTextValue(this, c.ConvertToInvariantString(ctx, instance)); return new XamlTextValue(this, c.ConvertToInvariantString(ctx, instance));
} }
string ns = GetNamespaceFor(elementType);
XmlElement xml = _xmlDoc.CreateElement(elementType.Name, GetNamespaceFor(elementType)); string prefix = GetPrefixForNamespace(ns);
XmlElement xml = _xmlDoc.CreateElement(prefix, elementType.Name, ns);
if (hasStringConverter && if (hasStringConverter &&
XamlObject.GetContentPropertyName(elementType) != null) XamlObject.GetContentPropertyName(elementType) != null)
{ {
@ -181,6 +185,44 @@ namespace ICSharpCode.WpfDesign.XamlDom
internal string GetNamespaceFor(Type type) internal string GetNamespaceFor(Type type)
{ {
return _typeFinder.GetXmlNamespaceFor(type.Assembly, type.Namespace); return _typeFinder.GetXmlNamespaceFor(type.Assembly, type.Namespace);
} }
internal string GetPrefixForNamespace(string @namespace)
{
if (@namespace == XamlConstants.PresentationNamespace)
{
return null;
}
string prefix = _xmlDoc.DocumentElement.GetPrefixOfNamespace(@namespace);
if (String.IsNullOrEmpty(prefix))
{
prefix = _typeFinder.GetPrefixForXmlNamespace(@namespace);
string existingNamespaceForPrefix = null;
if (!String.IsNullOrEmpty(prefix))
{
existingNamespaceForPrefix = _xmlDoc.DocumentElement.GetNamespaceOfPrefix(prefix);
}
if (String.IsNullOrEmpty(prefix) ||
!String.IsNullOrEmpty(existingNamespaceForPrefix) &&
existingNamespaceForPrefix != @namespace)
{
do
{
prefix = "Controls" + namespacePrefixCounter++;
} while (!String.IsNullOrEmpty(_xmlDoc.DocumentElement.GetNamespaceOfPrefix(prefix)));
}
string xmlnsPrefix = _xmlDoc.DocumentElement.GetPrefixOfNamespace(XamlConstants.XmlnsNamespace);
System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(xmlnsPrefix));
_xmlDoc.DocumentElement.SetAttribute(xmlnsPrefix + ":" + prefix, @namespace);
}
return prefix;
}
} }
} }

48
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs

@ -42,11 +42,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
} }
sealed class XamlNamespace sealed class XamlNamespace
{ {
internal readonly string XmlNamespacePrefix;
internal readonly string XmlNamespace; internal readonly string XmlNamespace;
internal XamlNamespace(string xmlNamespace) internal XamlNamespace(string xmlNamespacePrefix, string xmlNamespace)
{ {
this.XmlNamespacePrefix = xmlNamespacePrefix;
this.XmlNamespace = xmlNamespace; this.XmlNamespace = xmlNamespace;
} }
@ -54,7 +56,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
internal XamlNamespace Clone() internal XamlNamespace Clone()
{ {
XamlNamespace copy = new XamlNamespace(this.XmlNamespace); XamlNamespace copy = new XamlNamespace(this.XmlNamespacePrefix, this.XmlNamespace);
// AssemblyNamespaceMapping is immutable // AssemblyNamespaceMapping is immutable
copy.ClrNamespaces.AddRange(this.ClrNamespaces); copy.ClrNamespaces.AddRange(this.ClrNamespaces);
return copy; return copy;
@ -107,7 +109,25 @@ namespace ICSharpCode.WpfDesign.XamlDom
} else { } else {
return "clr-namespace:" + mapping.Namespace + ";assembly=" + mapping.Assembly.GetName().Name; return "clr-namespace:" + mapping.Namespace + ";assembly=" + mapping.Assembly.GetName().Name;
} }
} }
/// <summary>
/// Gets the prefix to use for the specified XML namespace,
/// or null if no suitable prefix could be found.
/// </summary>
public string GetPrefixForXmlNamespace(string xmlNamespace)
{
XamlNamespace ns;
if (namespaces.TryGetValue(xmlNamespace, out ns))
{
return ns.XmlNamespacePrefix;
}
else
{
return null;
}
}
XamlNamespace ParseNamespace(string xmlNamespace) XamlNamespace ParseNamespace(string xmlNamespace)
{ {
@ -127,7 +147,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
} }
assembly = name.Substring("assembly=".Length); assembly = name.Substring("assembly=".Length);
} }
XamlNamespace ns = new XamlNamespace(xmlNamespace); XamlNamespace ns = new XamlNamespace(null, xmlNamespace);
Assembly asm = LoadAssembly(assembly); Assembly asm = LoadAssembly(assembly);
if (asm != null) { if (asm != null) {
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(asm, namespaceName)); AddMappingToNamespace(ns, new AssemblyNamespaceMapping(asm, namespaceName));
@ -154,11 +174,19 @@ namespace ICSharpCode.WpfDesign.XamlDom
public void RegisterAssembly(Assembly assembly) public void RegisterAssembly(Assembly assembly)
{ {
if (assembly == null) if (assembly == null)
throw new ArgumentNullException("assembly"); throw new ArgumentNullException("assembly");
Dictionary<string, string> namespacePrefixes = new Dictionary<string, string>();
foreach (XmlnsPrefixAttribute xmlnsPrefix in assembly.GetCustomAttributes(typeof(XmlnsPrefixAttribute), true)) {
namespacePrefixes.Add(xmlnsPrefix.XmlNamespace, xmlnsPrefix.Prefix);
}
foreach (XmlnsDefinitionAttribute xmlnsDef in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), true)) { foreach (XmlnsDefinitionAttribute xmlnsDef in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), true)) {
XamlNamespace ns; XamlNamespace ns;
if (!namespaces.TryGetValue(xmlnsDef.XmlNamespace, out ns)) { if (!namespaces.TryGetValue(xmlnsDef.XmlNamespace, out ns)) {
ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace(xmlnsDef.XmlNamespace); string prefix;
namespacePrefixes.TryGetValue(xmlnsDef.XmlNamespace, out prefix);
ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace(prefix, xmlnsDef.XmlNamespace);
} }
if (string.IsNullOrEmpty(xmlnsDef.AssemblyName)) { if (string.IsNullOrEmpty(xmlnsDef.AssemblyName)) {
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(assembly, xmlnsDef.ClrNamespace)); AddMappingToNamespace(ns, new AssemblyNamespaceMapping(assembly, xmlnsDef.ClrNamespace));

Loading…
Cancel
Save