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/43/head
Tobias Gummesson 12 years ago
parent
commit
8df438f735
  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 @@ -17,7 +17,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlObject _rootElement;
IServiceProvider _serviceProvider;
XamlTypeFinder _typeFinder;
XamlTypeFinder _typeFinder;
int namespacePrefixCounter;
internal XmlDocument XmlDocument {
get { return _xmlDoc; }
@ -164,11 +166,13 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -164,11 +166,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
bool hasStringConverter = c.CanConvertTo(ctx, typeof(string)) && c.CanConvertFrom(typeof(string));
if (forProperty != null && hasStringConverter) {
return new XamlTextValue(this, c.ConvertToInvariantString(ctx, instance));
}
XmlElement xml = _xmlDoc.CreateElement(elementType.Name, GetNamespaceFor(elementType));
}
string ns = GetNamespaceFor(elementType);
string prefix = GetPrefixForNamespace(ns);
XmlElement xml = _xmlDoc.CreateElement(prefix, elementType.Name, ns);
if (hasStringConverter &&
XamlObject.GetContentPropertyName(elementType) != null)
{
@ -181,6 +185,44 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -181,6 +185,44 @@ namespace ICSharpCode.WpfDesign.XamlDom
internal string GetNamespaceFor(Type type)
{
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 @@ -42,11 +42,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
sealed class XamlNamespace
{
{
internal readonly string XmlNamespacePrefix;
internal readonly string XmlNamespace;
internal XamlNamespace(string xmlNamespace)
{
internal XamlNamespace(string xmlNamespacePrefix, string xmlNamespace)
{
this.XmlNamespacePrefix = xmlNamespacePrefix;
this.XmlNamespace = xmlNamespace;
}
@ -54,7 +56,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -54,7 +56,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
internal XamlNamespace Clone()
{
XamlNamespace copy = new XamlNamespace(this.XmlNamespace);
XamlNamespace copy = new XamlNamespace(this.XmlNamespacePrefix, this.XmlNamespace);
// AssemblyNamespaceMapping is immutable
copy.ClrNamespaces.AddRange(this.ClrNamespaces);
return copy;
@ -107,7 +109,25 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -107,7 +109,25 @@ namespace ICSharpCode.WpfDesign.XamlDom
} else {
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)
{
@ -127,7 +147,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -127,7 +147,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
assembly = name.Substring("assembly=".Length);
}
XamlNamespace ns = new XamlNamespace(xmlNamespace);
XamlNamespace ns = new XamlNamespace(null, xmlNamespace);
Assembly asm = LoadAssembly(assembly);
if (asm != null) {
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(asm, namespaceName));
@ -154,11 +174,19 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -154,11 +174,19 @@ namespace ICSharpCode.WpfDesign.XamlDom
public void RegisterAssembly(Assembly assembly)
{
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)) {
XamlNamespace ns;
if (!namespaces.TryGetValue(xmlnsDef.XmlNamespace, out ns)) {
ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace(xmlnsDef.XmlNamespace);
XamlNamespace ns;
if (!namespaces.TryGetValue(xmlnsDef.XmlNamespace, out ns)) {
string prefix;
namespacePrefixes.TryGetValue(xmlnsDef.XmlNamespace, out prefix);
ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace(prefix, xmlnsDef.XmlNamespace);
}
if (string.IsNullOrEmpty(xmlnsDef.AssemblyName)) {
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(assembly, xmlnsDef.ClrNamespace));

Loading…
Cancel
Save