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 eac9571842..6983391839 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SamplesTests.cs
@@ -112,6 +112,21 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom
Go To Page 2
+");
+ }
+
+ [Test]
+ public void Resources()
+ {
+ TestLoading(@"
+
+
+
+
+
");
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs
index e4730774ea..2194cf2613 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs
@@ -21,9 +21,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
public static bool IsCollectionType(Type type)
{
return typeof(IList).IsAssignableFrom(type)
- || typeof(IDictionary).IsAssignableFrom(type)
|| type.IsArray
- || typeof(IAddChild).IsAssignableFrom(type);
+ || typeof(IAddChild).IsAssignableFrom(type)
+ || typeof(ResourceDictionary).IsAssignableFrom(type);
}
public static void AddToCollection(Type collectionType, object collectionInstance, XamlPropertyValue newElement)
@@ -35,6 +35,14 @@ namespace ICSharpCode.WpfDesign.XamlDom
} else {
addChild.AddChild(newElement.GetValueFor(null));
}
+ } else if (collectionInstance is ResourceDictionary) {
+ object val = newElement.GetValueFor(null);
+ object key = newElement is XamlObject ? ((XamlObject)newElement).GetXamlAttribute("Key") : null;
+ if (key == null) {
+ if (val is Style)
+ key = ((Style)val).TargetType;
+ }
+ ((ResourceDictionary)collectionInstance).Add(key, val);
} else {
collectionType.InvokeMember(
"Add", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance,
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs
index 58d93af3c2..4c70c356af 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
@@ -218,10 +219,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
static class MarkupExtensionParser
{
- public static MarkupExtension ConstructMarkupExtension(string attributeText, XmlElement containingElement, XamlDocument document)
+ public static MarkupExtension ConstructMarkupExtension(string attributeText, XamlObject containingObject, XamlTypeResolverProvider typeResolver)
{
- if (containingElement == null)
- throw new ArgumentNullException("containingElement");
+ if (containingObject == null)
+ throw new ArgumentNullException("containingObject");
+
+ Debug.WriteLine("ConstructMarkupExtension " + attributeText);
List markupExtensionTokens = MarkupExtensionTokenizer.Tokenize(attributeText);
if (markupExtensionTokens.Count < 3
@@ -233,26 +236,14 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
string typeName = markupExtensionTokens[1].Value;
- string typeNamespaceUri;
- string typeLocalName;
- if (typeName.Contains(":")) {
- typeNamespaceUri = containingElement.GetNamespaceOfPrefix(typeName.Substring(0, typeName.IndexOf(':')));
- typeLocalName = typeName.Substring(typeName.IndexOf(':') + 1);
- } else {
- typeNamespaceUri = containingElement.NamespaceURI;
- typeLocalName = typeName;
- }
- if (string.IsNullOrEmpty(typeNamespaceUri))
- throw new XamlMarkupExtensionParseException("Unrecognized namespace prefix in type " + typeName);
- Type extensionType = null;
- if (typeNamespaceUri == "http://schemas.microsoft.com/winfx/2006/xaml" && typeLocalName == "Type") {
- extensionType = typeof(TypeExtension);
- } else {
- extensionType = document.TypeFinder.GetType(typeNamespaceUri, typeLocalName + "Extension");
- }
+ Type extensionType = typeResolver.Resolve(typeName + "Extension");
if (extensionType == null || !typeof(MarkupExtension).IsAssignableFrom(extensionType)) {
- throw new XamlMarkupExtensionParseException("Unknown markup extension " + typeLocalName + "Extension in " + typeNamespaceUri);
+ throw new XamlMarkupExtensionParseException("Unknown markup extension " + typeName + "Extension");
}
+ if (extensionType == typeof(TypeExtension))
+ extensionType = typeof(MyTypeExtension);
+ if (extensionType == typeof(System.Windows.StaticResourceExtension))
+ extensionType = typeof(MyStaticResourceExtension);
List positionalArgs = new List();
List> namedArgs = new List>();
@@ -280,10 +271,11 @@ namespace ICSharpCode.WpfDesign.XamlDom
var ctorParameters = ctors[0].GetParameters();
object[] ctorArguments = new object[positionalArgs.Count];
for (int i = 0; i < ctorArguments.Length; i++) {
- TypeConverter c = TypeDescriptor.GetConverter(ctorParameters[i].ParameterType);
+ Type parameterType = ctorParameters[i].ParameterType;
+ TypeConverter c = XamlNormalPropertyInfo.GetCustomTypeConverter(parameterType)
+ ?? TypeDescriptor.GetConverter(parameterType);
ctorArguments[i] = XamlTextValue.AttributeTextToObject(positionalArgs[i],
- containingElement,
- document,
+ containingObject,
c);
}
MarkupExtension result = (MarkupExtension)ctors[0].Invoke(ctorArguments);
@@ -299,8 +291,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
throw new XamlMarkupExtensionParseException("Property not found: " + extensionType.FullName + "." + memberName);
TypeConverter c = TypeDescriptor.GetConverter(property.PropertyType);
object propValue = XamlTextValue.AttributeTextToObject(pair.Value,
- containingElement,
- document,
+ containingObject,
c);
property.SetValue(result, propValue, null);
}
@@ -308,12 +299,25 @@ namespace ICSharpCode.WpfDesign.XamlDom
return result;
}
- sealed class TypeExtension : System.Windows.Markup.TypeExtension
+ sealed class MyTypeExtension : TypeExtension
{
- public TypeExtension() {}
+ public MyTypeExtension() {}
+
+ public MyTypeExtension(string typeName) : base(typeName) {}
+ }
+
+ sealed class MyStaticResourceExtension : System.Windows.StaticResourceExtension
+ {
+ public MyStaticResourceExtension() {}
+
+ public MyStaticResourceExtension(object resourceKey) : base(resourceKey) {}
- public TypeExtension(string typeName) : base(typeName)
+ public override object ProvideValue(IServiceProvider serviceProvider)
{
+ XamlTypeResolverProvider xamlTypeResolver = (XamlTypeResolverProvider)serviceProvider.GetService(typeof(XamlTypeResolverProvider));
+ if (xamlTypeResolver == null)
+ throw new XamlLoadException("XamlTypeResolverProvider not found.");
+ return xamlTypeResolver.FindResource(this.ResourceKey);
}
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
index fd1f55425c..1f09b7f412 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
@@ -77,5 +77,6 @@
+
\ No newline at end of file
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
index 1cfdc4fc4a..e754cc5aca 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
@@ -7,6 +7,7 @@
using System;
using System.ComponentModel;
+using System.Windows.Markup;
using System.Xml;
namespace ICSharpCode.WpfDesign.XamlDom
@@ -40,18 +41,29 @@ namespace ICSharpCode.WpfDesign.XamlDom
get { return _serviceProvider; }
}
- internal ITypeDescriptorContext GetTypeDescriptorContext()
+ ///
+ /// Gets the type descriptor context used for type conversions.
+ ///
+ /// The containing object, used when the
+ /// type descriptor context needs to resolve an XML namespace.
+ internal ITypeDescriptorContext GetTypeDescriptorContext(XamlObject containingObject)
{
- return new DummyTypeDescriptorContext(this);
+ return new DummyTypeDescriptorContext(this, containingObject);
}
sealed class DummyTypeDescriptorContext : ITypeDescriptorContext
{
- XamlDocument document;
+ IServiceProvider baseServiceProvider;
- public DummyTypeDescriptorContext(XamlDocument document)
+ public DummyTypeDescriptorContext(XamlDocument document, XamlObject containingObject)
{
- this.document = document;
+ if (containingObject != null) {
+ if (containingObject.OwnerDocument != document)
+ throw new ArgumentException("Containing object must belong to the document!");
+ baseServiceProvider = new XamlTypeResolverProvider(containingObject);
+ } else {
+ baseServiceProvider = document.ServiceProvider;
+ }
}
public IContainer Container {
@@ -77,7 +89,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
public object GetService(Type serviceType)
{
- return document.ServiceProvider.GetService(serviceType);
+ return baseServiceProvider.GetService(serviceType);
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
index 8524a83b97..391e849165 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
@@ -59,6 +59,24 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
#endregion
+ XamlObject parentObject;
+
+ ///
+ /// Gets the parent object.
+ ///
+ public XamlObject ParentObject {
+ get {
+ return parentObject;
+ }
+ internal set { parentObject = value; }
+ }
+
+ internal override void OnParentPropertyChanged()
+ {
+ parentObject = (ParentProperty != null) ? ParentProperty.ParentObject : null;
+ base.OnParentPropertyChanged();
+ }
+
internal XmlElement XmlElement {
get { return element; }
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
index e4bfbfac0e..53d4a27bf4 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
@@ -108,7 +108,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
Type FindType(string namespaceUri, string localName)
{
- Type elementType = settings.TypeFinder.GetType(namespaceUri, localName);
+ return FindType(settings.TypeFinder, namespaceUri, localName);
+ }
+
+ static Type FindType(XamlTypeFinder typeFinder, string namespaceUri, string localName)
+ {
+ Type elementType = typeFinder.GetType(namespaceUri, localName);
if (elementType == null)
throw new XamlLoadException("Cannot find type " + localName + " in " + namespaceUri);
return elementType;
@@ -124,12 +129,14 @@ namespace ICSharpCode.WpfDesign.XamlDom
readonly static object[] emptyObjectArray = new object[0];
XmlSpace currentXmlSpace = XmlSpace.None;
+ XamlObject currentXamlObject;
XamlObject ParseObject(XmlElement element)
{
Type elementType = FindType(element.NamespaceURI, element.LocalName);
XmlSpace oldXmlSpace = currentXmlSpace;
+ XamlObject parentXamlObject = currentXamlObject;
if (element.HasAttribute("xml:space")) {
currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), element.GetAttribute("xml:space"), true);
}
@@ -160,7 +167,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
object instance;
if (initializeFromTextValueInsteadOfConstructor != null) {
instance = TypeDescriptor.GetConverter(elementType).ConvertFromString(
- document.GetTypeDescriptorContext(),
+ document.GetTypeDescriptorContext(null),
CultureInfo.InvariantCulture,
initializeFromTextValueInsteadOfConstructor.Text);
} else {
@@ -168,6 +175,8 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
XamlObject obj = new XamlObject(document, element, elementType, instance);
+ currentXamlObject = obj;
+ obj.ParentObject = parentXamlObject;
ISupportInitialize iSupportInitializeInstance = instance as ISupportInitialize;
if (iSupportInitializeInstance != null) {
@@ -185,12 +194,28 @@ namespace ICSharpCode.WpfDesign.XamlDom
ParseObjectAttribute(obj, attribute);
}
+ if (!(obj.Instance is Style)) {
+ ParseObjectContent(obj, element, defaultProperty, initializeFromTextValueInsteadOfConstructor);
+ }
+
+ if (iSupportInitializeInstance != null) {
+ iSupportInitializeInstance.EndInit();
+ }
+
+ currentXmlSpace = oldXmlSpace;
+ currentXamlObject = parentXamlObject;
+
+ return obj;
+ }
+
+ void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
+ {
XamlPropertyValue setDefaultValueTo = null;
object defaultPropertyValue = null;
XamlProperty defaultCollectionProperty = null;
if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty) {
- defaultPropertyValue = defaultProperty.GetValue(instance);
+ defaultPropertyValue = defaultProperty.GetValue(obj.Instance);
obj.AddProperty(defaultCollectionProperty = new XamlProperty(obj, defaultProperty));
}
@@ -200,7 +225,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
// here, but let's try to imitate it as good as possible
if (defaultProperty != null && !defaultProperty.IsCollection) {
for (; combinedNormalizedChildNodes > 0; combinedNormalizedChildNodes--) {
- defaultProperty.GetValue(instance);
+ defaultProperty.GetValue(obj.Instance);
}
}
@@ -213,7 +238,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
// I don't know why the official XamlReader runs the property getter
// here, but let's try to imitate it as good as possible
if (defaultProperty != null && !defaultProperty.IsCollection) {
- defaultProperty.GetValue(instance);
+ defaultProperty.GetValue(obj.Instance);
}
ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty, defaultPropertyValue);
continue;
@@ -224,8 +249,8 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlPropertyValue childValue = ParseValue(childNode);
if (childValue != null) {
if (defaultProperty != null && defaultProperty.IsCollection) {
- CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
+ CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
} else {
if (setDefaultValueTo != null)
throw new XamlLoadException("default property may have only one value assigned");
@@ -238,23 +263,15 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
// Runs even when defaultValueSet==false!
// Again, no idea why the official XamlReader does this.
- defaultProperty.GetValue(instance);
+ defaultProperty.GetValue(obj.Instance);
}
if (setDefaultValueTo != null) {
if (defaultProperty == null) {
throw new XamlLoadException("This element does not have a default value, cannot assign to it");
}
- defaultProperty.SetValue(instance, setDefaultValueTo.GetValueFor(defaultProperty));
obj.AddProperty(new XamlProperty(obj, defaultProperty, setDefaultValueTo));
+ defaultProperty.SetValue(obj.Instance, setDefaultValueTo.GetValueFor(defaultProperty));
}
-
- if (iSupportInitializeInstance != null) {
- iSupportInitializeInstance.EndInit();
- }
-
- currentXmlSpace = oldXmlSpace;
-
- return obj;
}
int combinedNormalizedChildNodes;
@@ -319,7 +336,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
return null;
}
- static XamlPropertyInfo FindProperty(object elementInstance, Type propertyType, string propertyName)
+ internal static XamlPropertyInfo FindProperty(object elementInstance, Type propertyType, string propertyName)
{
PropertyDescriptorCollection properties;
if (elementInstance != null) {
@@ -375,17 +392,17 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlPropertyInfo GetPropertyInfo(object elementInstance, Type elementType, XmlAttribute attribute)
{
if (attribute.LocalName.Contains(".")) {
- return GetPropertyInfo(elementInstance, elementType, GetAttributeNamespace(attribute), attribute.LocalName);
+ return GetPropertyInfo(settings.TypeFinder, elementInstance, elementType, GetAttributeNamespace(attribute), attribute.LocalName);
} else {
return FindProperty(elementInstance, elementType, attribute.LocalName);
}
}
- XamlPropertyInfo GetPropertyInfo(object elementInstance, Type elementType, string xmlNamespace, string localName)
+ internal static XamlPropertyInfo GetPropertyInfo(XamlTypeFinder typeFinder, object elementInstance, Type elementType, string xmlNamespace, string localName)
{
string typeName, propertyName;
SplitQualifiedIdentifier(localName, out typeName, out propertyName);
- Type propertyType = FindType(xmlNamespace, typeName);
+ Type propertyType = FindType(typeFinder, xmlNamespace, typeName);
if (elementType == propertyType || propertyType.IsAssignableFrom(elementType)) {
return FindProperty(elementInstance, propertyType, propertyName);
} else {
@@ -406,8 +423,8 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
XamlPropertyInfo propertyInfo = GetPropertyInfo(obj.Instance, obj.ElementType, attribute);
XamlTextValue textValue = new XamlTextValue(document, attribute);
- propertyInfo.SetValue(obj.Instance, textValue.GetValueFor(propertyInfo));
obj.AddProperty(new XamlProperty(obj, propertyInfo, textValue));
+ propertyInfo.SetValue(obj.Instance, textValue.GetValueFor(propertyInfo));
}
static bool ObjectChildElementIsPropertyElement(XmlElement element)
@@ -420,7 +437,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
Debug.Assert(element.LocalName.Contains("."));
// this is a element property syntax
- XamlPropertyInfo propertyInfo = GetPropertyInfo(obj.Instance, obj.ElementType, element.NamespaceURI, element.LocalName);
+ XamlPropertyInfo propertyInfo = GetPropertyInfo(settings.TypeFinder, obj.Instance, obj.ElementType, element.NamespaceURI, element.LocalName);
bool valueWasSet = false;
object collectionInstance = null;
@@ -458,10 +475,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (valueWasSet)
throw new XamlLoadException("non-collection property may have only one child element");
valueWasSet = true;
- propertyInfo.SetValue(obj.Instance, childValue.GetValueFor(propertyInfo));
XamlProperty xp = new XamlProperty(obj, propertyInfo, childValue);
xp.ParserSetPropertyElement(element);
obj.AddProperty(xp);
+ propertyInfo.SetValue(obj.Instance, childValue.GetValueFor(propertyInfo));
}
}
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs
index 104230c949..8282b9f550 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs
@@ -42,6 +42,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
readonly DependencyProperty property;
readonly bool isAttached;
+ public DependencyProperty Property {
+ get { return property; }
+ }
+
public XamlDependencyPropertyInfo(DependencyProperty property, bool isAttached)
{
Debug.Assert(property != null);
@@ -101,7 +105,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
#endregion
-
+
#region XamlNormalPropertyInfo
internal sealed class XamlNormalPropertyInfo : XamlPropertyInfo
{
@@ -141,10 +145,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
public override TypeConverter TypeConverter {
get {
- if (_propertyDescriptor.PropertyType == typeof(object))
- return null;
- else
- return _propertyDescriptor.Converter;
+ return GetCustomTypeConverter(_propertyDescriptor.PropertyType) ?? _propertyDescriptor.Converter;
}
}
@@ -167,6 +168,84 @@ namespace ICSharpCode.WpfDesign.XamlDom
return CollectionSupport.IsCollectionType(_propertyDescriptor.PropertyType);
}
}
+
+ public static readonly TypeConverter StringTypeConverter = TypeDescriptor.GetConverter(typeof(string));
+
+ public static TypeConverter GetCustomTypeConverter(Type propertyType)
+ {
+ if (propertyType == typeof(object))
+ return StringTypeConverter;
+ else if (propertyType == typeof(Type))
+ return TypeTypeConverter.Instance;
+ else if (propertyType == typeof(DependencyProperty))
+ return DependencyPropertyConverter.Instance;
+ else
+ return null;
+ }
+
+ sealed class TypeTypeConverter : TypeConverter
+ {
+ public readonly static TypeTypeConverter Instance = new TypeTypeConverter();
+
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ return true;
+ else
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value == null)
+ return null;
+ if (value is string) {
+ IXamlTypeResolver xamlTypeResolver = (IXamlTypeResolver)context.GetService(typeof(IXamlTypeResolver));
+ if (xamlTypeResolver == null)
+ throw new XamlLoadException("IXamlTypeResolver not found in type descriptor context.");
+ return xamlTypeResolver.Resolve((string)value);
+ } else {
+ return base.ConvertFrom(context, culture, value);
+ }
+ }
+ }
+
+ sealed class DependencyPropertyConverter : TypeConverter
+ {
+ public readonly static DependencyPropertyConverter Instance = new DependencyPropertyConverter();
+
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ return true;
+ else
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value == null)
+ return null;
+ if (value is string) {
+ XamlTypeResolverProvider xamlTypeResolver = (XamlTypeResolverProvider)context.GetService(typeof(XamlTypeResolverProvider));
+ if (xamlTypeResolver == null)
+ throw new XamlLoadException("XamlTypeResolverProvider not found in type descriptor context.");
+ XamlPropertyInfo prop = xamlTypeResolver.ResolveProperty((string)value);
+ if (prop == null)
+ throw new XamlLoadException("Could not find property " + value + ".");
+ XamlDependencyPropertyInfo depProp = prop as XamlDependencyPropertyInfo;
+ if (depProp != null)
+ return depProp.Property;
+ FieldInfo field = prop.TargetType.GetField(prop.Name + "Property", BindingFlags.Public | BindingFlags.Static);
+ if (field != null && field.FieldType == typeof(DependencyProperty)) {
+ return (DependencyProperty)field.GetValue(null);
+ }
+ throw new XamlLoadException("Property " + value + " is not a dependency property.");
+ } else {
+ return base.ConvertFrom(context, culture, value);
+ }
+ }
+ }
}
#endregion
@@ -208,7 +287,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
public override TypeConverter TypeConverter {
- get { return null; }
+ get { return XamlNormalPropertyInfo.StringTypeConverter; }
}
public override string FullyQualifiedName {
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTextValue.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTextValue.cs
index 42309c49fe..a967ad50d9 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTextValue.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTextValue.cs
@@ -109,83 +109,40 @@ namespace ICSharpCode.WpfDesign.XamlDom
return b.ToString();
}
- static readonly TypeConverter stringTypeConverter = TypeDescriptor.GetConverter(typeof(string));
-
internal override object GetValueFor(XamlPropertyInfo targetProperty)
{
+ if (ParentProperty == null)
+ throw new InvalidOperationException("Cannot call GetValueFor while ParentProperty is null");
if (attribute != null) {
- return AttributeTextToObject(attribute.Value, attribute.OwnerElement, document,
- targetProperty != null ? targetProperty.TypeConverter : stringTypeConverter);
+ return AttributeTextToObject(attribute.Value, ParentProperty.ParentObject,
+ targetProperty != null ? targetProperty.TypeConverter : XamlNormalPropertyInfo.StringTypeConverter);
}
if (targetProperty == null)
return this.Text;
- TypeConverter converter = targetProperty.TypeConverter;
- if (converter != null) {
- return converter.ConvertFromString(document.GetTypeDescriptorContext(), CultureInfo.InvariantCulture, this.Text);
- } else {
- return this.Text;
- }
+ return targetProperty.TypeConverter.ConvertFromString(
+ document.GetTypeDescriptorContext(ParentProperty.ParentObject),
+ CultureInfo.InvariantCulture, this.Text);
}
- internal static object AttributeTextToObject(string attributeText, XmlElement containingElement,
- XamlDocument document, TypeConverter typeConverter)
+ internal static object AttributeTextToObject(string attributeText, XamlObject containingObject,
+ TypeConverter typeConverter)
{
- if (typeConverter == null)
- typeConverter = stringTypeConverter;
if (attributeText.StartsWith("{}")) {
return typeConverter.ConvertFromString(
- document.GetTypeDescriptorContext(), CultureInfo.InvariantCulture,
+ containingObject.OwnerDocument.GetTypeDescriptorContext(containingObject), CultureInfo.InvariantCulture,
attributeText.Substring(2));
} else if (attributeText.StartsWith("{")) {
- XamlTypeResolverProvider xtrp = new XamlTypeResolverProvider(document, containingElement, document.ServiceProvider);
+ XamlTypeResolverProvider xtrp = new XamlTypeResolverProvider(containingObject);
MarkupExtension extension = MarkupExtensionParser.ConstructMarkupExtension(
- attributeText, containingElement, document);
+ attributeText, containingObject, xtrp);
return extension.ProvideValue(xtrp);
} else {
return typeConverter.ConvertFromString(
- document.GetTypeDescriptorContext(), CultureInfo.InvariantCulture,
+ containingObject.OwnerDocument.GetTypeDescriptorContext(containingObject), CultureInfo.InvariantCulture,
attributeText);
}
}
- sealed class XamlTypeResolverProvider : IXamlTypeResolver, IServiceProvider
- {
- XamlDocument document;
- XmlElement containingElement;
- IServiceProvider baseProvider;
-
- public XamlTypeResolverProvider(XamlDocument document, XmlElement containingElement, IServiceProvider baseProvider)
- {
- this.document = document;
- this.containingElement = containingElement;
- this.baseProvider = baseProvider;
- }
-
- public Type Resolve(string typeName)
- {
- string typeNamespaceUri;
- string typeLocalName;
- if (typeName.Contains(":")) {
- typeNamespaceUri = containingElement.GetNamespaceOfPrefix(typeName.Substring(0, typeName.IndexOf(':')));
- typeLocalName = typeName.Substring(typeName.IndexOf(':') + 1);
- } else {
- typeNamespaceUri = containingElement.NamespaceURI;
- typeLocalName = typeName;
- }
- if (string.IsNullOrEmpty(typeNamespaceUri))
- throw new XamlMarkupExtensionParseException("Unrecognized namespace prefix in type " + typeName);
- return document.TypeFinder.GetType(typeNamespaceUri, typeLocalName);
- }
-
- public object GetService(Type serviceType)
- {
- if (serviceType == typeof(IXamlTypeResolver))
- return this;
- else
- return baseProvider.GetService(serviceType);
- }
- }
-
internal override void RemoveNodeFromParent()
{
if (attribute != null)
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
new file mode 100644
index 0000000000..b1a19250f2
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs
@@ -0,0 +1,102 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Globalization;
+using System.Text;
+using System.Windows;
+using System.Windows.Markup;
+using System.Xml;
+
+namespace ICSharpCode.WpfDesign.XamlDom
+{
+ sealed class XamlTypeResolverProvider : IXamlTypeResolver, IServiceProvider
+ {
+ XamlDocument document;
+ XamlObject containingObject;
+ XmlElement containingElement;
+
+ public XamlTypeResolverProvider(XamlObject containingObject)
+ {
+ if (containingObject == null)
+ throw new ArgumentNullException("containingObject");
+ this.document = containingObject.OwnerDocument;
+ this.containingObject = containingObject;
+ this.containingElement = containingObject.XmlElement;
+ }
+
+ public Type Resolve(string typeName)
+ {
+ string typeNamespaceUri;
+ string typeLocalName;
+ if (typeName.Contains(":")) {
+ typeNamespaceUri = containingElement.GetNamespaceOfPrefix(typeName.Substring(0, typeName.IndexOf(':')));
+ typeLocalName = typeName.Substring(typeName.IndexOf(':') + 1);
+ } else {
+ typeNamespaceUri = containingElement.NamespaceURI;
+ typeLocalName = typeName;
+ }
+ if (string.IsNullOrEmpty(typeNamespaceUri))
+ throw new XamlMarkupExtensionParseException("Unrecognized namespace prefix in type " + typeName);
+ return document.TypeFinder.GetType(typeNamespaceUri, typeLocalName);
+ }
+
+ public object GetService(Type serviceType)
+ {
+ if (serviceType == typeof(IXamlTypeResolver) || serviceType == typeof(XamlTypeResolverProvider))
+ return this;
+ else
+ return document.ServiceProvider.GetService(serviceType);
+ }
+
+ public XamlPropertyInfo ResolveProperty(string propertyName)
+ {
+ string propertyNamespace;
+ if (propertyName.Contains(":")) {
+ propertyNamespace = containingElement.GetNamespaceOfPrefix(propertyName.Substring(0, propertyName.IndexOf(':')));
+ propertyName = propertyName.Substring(propertyName.IndexOf(':') + 1);
+ } else {
+ propertyNamespace = containingElement.NamespaceURI;
+ }
+ Type elementType = null;
+ XamlObject obj = containingObject;
+ while (obj != null) {
+ Style style = obj.Instance as Style;
+ if (style != null && style.TargetType != null) {
+ elementType = style.TargetType;
+ break;
+ }
+ obj = obj.ParentObject;
+ }
+ if (propertyName.Contains(".")) {
+ return XamlParser.GetPropertyInfo(document.TypeFinder, null, elementType, propertyNamespace, propertyName);
+ } else if (elementType != null) {
+ return XamlParser.FindProperty(null, elementType, propertyName);
+ } else {
+ return null;
+ }
+ }
+
+ public object FindResource(object key)
+ {
+ XamlObject obj = containingObject;
+ while (obj != null) {
+ FrameworkElement el = obj.Instance as FrameworkElement;
+ if (el != null) {
+ object val = el.Resources[key];
+ if (val != null)
+ return val;
+ }
+ obj = obj.ParentObject;
+ }
+ return null;
+ }
+ }
+}