You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
316 lines
8.4 KiB
316 lines
8.4 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt"/> |
|
// <license see="prj:///doc/license.txt"/> |
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
|
|
using System; |
|
using System.Diagnostics; |
|
using System.Collections; |
|
using System.ComponentModel; |
|
using System.Globalization; |
|
using System.Reflection; |
|
using System.Windows; |
|
using System.Windows.Markup; |
|
|
|
namespace ICSharpCode.WpfDesign.XamlDom |
|
{ |
|
/// <summary> |
|
/// Represents a property assignable in XAML. |
|
/// This can be a normal .NET property or an attached property. |
|
/// </summary> |
|
internal abstract class XamlPropertyInfo |
|
{ |
|
public abstract object GetValue(object instance); |
|
public abstract void SetValue(object instance, object value); |
|
public abstract void ResetValue(object instance); |
|
public abstract TypeConverter TypeConverter { get; } |
|
public abstract Type TargetType { get; } |
|
public abstract Type ReturnType { get; } |
|
public abstract string Name { get; } |
|
public abstract string FullyQualifiedName { get; } |
|
public abstract bool IsAttached { get; } |
|
public abstract bool IsCollection { get; } |
|
public virtual bool IsEvent { get { return false; } } |
|
public abstract string Category { get; } |
|
} |
|
|
|
#region XamlDependencyPropertyInfo |
|
internal class XamlDependencyPropertyInfo : XamlPropertyInfo |
|
{ |
|
readonly DependencyProperty property; |
|
readonly bool isAttached; |
|
|
|
public DependencyProperty Property { |
|
get { return property; } |
|
} |
|
|
|
public XamlDependencyPropertyInfo(DependencyProperty property, bool isAttached) |
|
{ |
|
Debug.Assert(property != null); |
|
this.property = property; |
|
this.isAttached = isAttached; |
|
} |
|
|
|
public override TypeConverter TypeConverter { |
|
get { |
|
return TypeDescriptor.GetConverter(this.ReturnType); |
|
} |
|
} |
|
|
|
public override string FullyQualifiedName { |
|
get { |
|
return this.TargetType.FullName + "." + this.Name; |
|
} |
|
} |
|
|
|
public override Type TargetType { |
|
get { return property.OwnerType; } |
|
} |
|
|
|
public override Type ReturnType { |
|
get { return property.PropertyType; } |
|
} |
|
|
|
public override string Name { |
|
get { return property.Name; } |
|
} |
|
|
|
public override string Category { |
|
get { return "Misc"; } |
|
} |
|
|
|
public override bool IsAttached { |
|
get { return isAttached; } |
|
} |
|
|
|
public override bool IsCollection { |
|
get { return false; } |
|
} |
|
|
|
public override object GetValue(object instance) |
|
{ |
|
return ((DependencyObject)instance).GetValue(property); |
|
} |
|
|
|
public override void SetValue(object instance, object value) |
|
{ |
|
((DependencyObject)instance).SetValue(property, value); |
|
} |
|
|
|
public override void ResetValue(object instance) |
|
{ |
|
((DependencyObject)instance).ClearValue(property); |
|
} |
|
} |
|
#endregion |
|
|
|
#region XamlNormalPropertyInfo |
|
internal sealed class XamlNormalPropertyInfo : XamlPropertyInfo |
|
{ |
|
PropertyDescriptor _propertyDescriptor; |
|
|
|
public XamlNormalPropertyInfo(PropertyDescriptor propertyDescriptor) |
|
{ |
|
this._propertyDescriptor = propertyDescriptor; |
|
} |
|
|
|
public override object GetValue(object instance) |
|
{ |
|
return _propertyDescriptor.GetValue(instance); |
|
} |
|
|
|
public override void SetValue(object instance, object value) |
|
{ |
|
_propertyDescriptor.SetValue(instance, value); |
|
} |
|
|
|
public override void ResetValue(object instance) |
|
{ |
|
_propertyDescriptor.ResetValue(instance); |
|
} |
|
|
|
public override Type ReturnType { |
|
get { return _propertyDescriptor.PropertyType; } |
|
} |
|
|
|
public override Type TargetType { |
|
get { return _propertyDescriptor.ComponentType; } |
|
} |
|
|
|
public override string Category { |
|
get { return _propertyDescriptor.Category; } |
|
} |
|
|
|
public override TypeConverter TypeConverter { |
|
get { |
|
return GetCustomTypeConverter(_propertyDescriptor.PropertyType) ?? _propertyDescriptor.Converter; |
|
} |
|
} |
|
|
|
public override string FullyQualifiedName { |
|
get { |
|
return _propertyDescriptor.ComponentType.FullName + "." + _propertyDescriptor.Name; |
|
} |
|
} |
|
|
|
public override string Name { |
|
get { return _propertyDescriptor.Name; } |
|
} |
|
|
|
public override bool IsAttached { |
|
get { return false; } |
|
} |
|
|
|
public override bool IsCollection { |
|
get { |
|
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 |
|
|
|
#region XamlEventPropertyInfo |
|
sealed class XamlEventPropertyInfo : XamlPropertyInfo |
|
{ |
|
readonly EventDescriptor _eventDescriptor; |
|
|
|
public XamlEventPropertyInfo(EventDescriptor eventDescriptor) |
|
{ |
|
this._eventDescriptor = eventDescriptor; |
|
} |
|
|
|
public override object GetValue(object instance) |
|
{ |
|
throw new NotSupportedException(); |
|
} |
|
|
|
public override void SetValue(object instance, object value) |
|
{ |
|
|
|
} |
|
|
|
public override void ResetValue(object instance) |
|
{ |
|
|
|
} |
|
|
|
public override Type ReturnType { |
|
get { return _eventDescriptor.EventType; } |
|
} |
|
|
|
public override Type TargetType { |
|
get { return _eventDescriptor.ComponentType; } |
|
} |
|
|
|
public override string Category { |
|
get { return _eventDescriptor.Category; } |
|
} |
|
|
|
public override TypeConverter TypeConverter { |
|
get { return XamlNormalPropertyInfo.StringTypeConverter; } |
|
} |
|
|
|
public override string FullyQualifiedName { |
|
get { |
|
return _eventDescriptor.ComponentType.FullName + "." + _eventDescriptor.Name; |
|
} |
|
} |
|
|
|
public override string Name { |
|
get { return _eventDescriptor.Name; } |
|
} |
|
|
|
public override bool IsEvent { |
|
get { return true; } |
|
} |
|
|
|
public override bool IsAttached { |
|
get { return false; } |
|
} |
|
|
|
public override bool IsCollection { |
|
get { return false; } |
|
} |
|
} |
|
#endregion |
|
}
|
|
|