a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
305 lines
8.2 KiB
C#
305 lines
8.2 KiB
C#
//
|
|
// System.ComponentModel.PropertyDescriptor.cs
|
|
//
|
|
// Author:
|
|
// Miguel de Icaza (miguel@ximian.com)
|
|
// Andreas Nahr (ClassDevelopment@A-SoftTech.com)
|
|
// Ivan N. Zlatev (contact@i-nz.net)
|
|
//
|
|
// (C) Ximian, Inc. http://www.ximian.com
|
|
// (C) 2003 Andreas Nahr
|
|
// (C) 2008 Novell, Inc. http://www.novell.com
|
|
//
|
|
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace System.ComponentModel
|
|
{
|
|
[ComVisible (true)]
|
|
public abstract class PropertyDescriptor : MemberDescriptor
|
|
{
|
|
TypeConverter converter;
|
|
|
|
protected PropertyDescriptor (MemberDescriptor reference)
|
|
: base (reference)
|
|
{
|
|
}
|
|
|
|
protected PropertyDescriptor (MemberDescriptor reference, Attribute [] attrs)
|
|
: base (reference, attrs)
|
|
{
|
|
}
|
|
|
|
protected PropertyDescriptor (string name, Attribute [] attrs)
|
|
: base (name, attrs)
|
|
{
|
|
}
|
|
|
|
public abstract Type ComponentType { get; }
|
|
|
|
public virtual TypeConverter Converter {
|
|
get {
|
|
if (converter == null && PropertyType != null) {
|
|
TypeConverterAttribute at = (TypeConverterAttribute) Attributes [typeof(TypeConverterAttribute)];
|
|
if (at != null && at != TypeConverterAttribute.Default) {
|
|
Type converterType = GetTypeFromName (at.ConverterTypeName);
|
|
if (converterType != null && typeof (TypeConverter).IsAssignableFrom (converterType))
|
|
converter = (TypeConverter)CreateInstance (converterType);
|
|
}
|
|
if (converter == null)
|
|
converter = TypeDescriptor.GetConverter (PropertyType);
|
|
}
|
|
return converter;
|
|
}
|
|
}
|
|
|
|
public virtual bool IsLocalizable {
|
|
get {
|
|
foreach (Attribute attr in AttributeArray){
|
|
if (attr is LocalizableAttribute)
|
|
return ((LocalizableAttribute) attr).IsLocalizable;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public abstract bool IsReadOnly { get; }
|
|
|
|
public abstract Type PropertyType { get; }
|
|
|
|
public virtual bool SupportsChangeEvents {
|
|
get { return false; }
|
|
}
|
|
|
|
public DesignerSerializationVisibility SerializationVisibility {
|
|
get {
|
|
foreach (Attribute attr in AttributeArray) {
|
|
if (attr is DesignerSerializationVisibilityAttribute){
|
|
DesignerSerializationVisibilityAttribute a;
|
|
|
|
a = (DesignerSerializationVisibilityAttribute) attr;
|
|
|
|
return a.Visibility;
|
|
}
|
|
}
|
|
|
|
return DesignerSerializationVisibility.Visible;
|
|
}
|
|
}
|
|
|
|
Hashtable notifiers;
|
|
|
|
public virtual void AddValueChanged (object component, EventHandler handler)
|
|
{
|
|
EventHandler component_notifiers;
|
|
|
|
if (component == null)
|
|
throw new ArgumentNullException ("component");
|
|
|
|
if (handler == null)
|
|
throw new ArgumentNullException ("handler");
|
|
|
|
if (notifiers == null)
|
|
notifiers = new Hashtable ();
|
|
|
|
component_notifiers = (EventHandler) notifiers [component];
|
|
|
|
if (component_notifiers != null) {
|
|
component_notifiers += handler;
|
|
notifiers [component] = component_notifiers;
|
|
} else {
|
|
notifiers [component] = handler;
|
|
}
|
|
}
|
|
|
|
public virtual void RemoveValueChanged (object component, System.EventHandler handler)
|
|
{
|
|
EventHandler component_notifiers;
|
|
|
|
if (component == null)
|
|
throw new ArgumentNullException ("component");
|
|
|
|
if (handler == null)
|
|
throw new ArgumentNullException ("handler");
|
|
|
|
if (notifiers == null) return;
|
|
|
|
component_notifiers = (EventHandler) notifiers [component];
|
|
component_notifiers -= handler;
|
|
|
|
if (component_notifiers == null)
|
|
notifiers.Remove (component);
|
|
else
|
|
notifiers [component] = component_notifiers;
|
|
}
|
|
|
|
protected override void FillAttributes (IList attributeList)
|
|
{
|
|
base.FillAttributes (attributeList);
|
|
}
|
|
|
|
protected override object GetInvocationTarget (Type type, object instance)
|
|
{
|
|
if (type == null)
|
|
throw new ArgumentNullException ("type");
|
|
if (instance == null)
|
|
throw new ArgumentNullException ("instance");
|
|
|
|
if (instance is CustomTypeDescriptor) {
|
|
CustomTypeDescriptor ctd = (CustomTypeDescriptor) instance;
|
|
return ctd.GetPropertyOwner (this);
|
|
}
|
|
|
|
return base.GetInvocationTarget (type, instance);
|
|
}
|
|
|
|
protected internal EventHandler GetValueChangedHandler (object component)
|
|
{
|
|
if (component == null || notifiers == null)
|
|
return null;
|
|
|
|
return (EventHandler) notifiers [component];
|
|
}
|
|
|
|
protected virtual void OnValueChanged (object component, EventArgs e)
|
|
{
|
|
if (notifiers == null)
|
|
return;
|
|
|
|
EventHandler component_notifiers = (EventHandler) notifiers [component];
|
|
|
|
if (component_notifiers == null)
|
|
return;
|
|
|
|
component_notifiers (component, e);
|
|
}
|
|
|
|
public abstract object GetValue (object component);
|
|
|
|
public abstract void SetValue (object component, object value);
|
|
|
|
public abstract void ResetValue (object component);
|
|
|
|
public abstract bool CanResetValue (object component);
|
|
|
|
public abstract bool ShouldSerializeValue (object component);
|
|
|
|
protected object CreateInstance (Type type)
|
|
{
|
|
if (type == null || PropertyType == null)
|
|
return null;
|
|
|
|
object instance = null;
|
|
Type[] paramTypes = new Type[] { typeof (Type) };
|
|
ConstructorInfo ctor = type.GetConstructor (paramTypes);
|
|
if (ctor != null) {
|
|
object[] parameters = new object[] { PropertyType };
|
|
instance = TypeDescriptor.CreateInstance (null, type, paramTypes, parameters);
|
|
} else {
|
|
instance = TypeDescriptor.CreateInstance (null, type, null, null);
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (!base.Equals (obj)) return false;
|
|
PropertyDescriptor other = obj as PropertyDescriptor;
|
|
if (other == null) return false;
|
|
return other.PropertyType == PropertyType;
|
|
}
|
|
|
|
public PropertyDescriptorCollection GetChildProperties()
|
|
{
|
|
return GetChildProperties (null, null);
|
|
}
|
|
|
|
public PropertyDescriptorCollection GetChildProperties(object instance)
|
|
{
|
|
return GetChildProperties (instance, null);
|
|
}
|
|
|
|
public PropertyDescriptorCollection GetChildProperties(Attribute[] filter)
|
|
{
|
|
return GetChildProperties (null, filter);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return base.GetHashCode ();
|
|
}
|
|
|
|
public virtual PropertyDescriptorCollection GetChildProperties (object instance, Attribute[] filter)
|
|
{
|
|
return TypeDescriptor.GetProperties (instance, filter);
|
|
}
|
|
|
|
public virtual object GetEditor (Type editorBaseType)
|
|
{
|
|
Type t = null;
|
|
Attribute [] atts = AttributeArray;
|
|
|
|
if (atts != null && atts.Length != 0) {
|
|
foreach (Attribute a in atts) {
|
|
EditorAttribute ea = a as EditorAttribute;
|
|
|
|
if (ea == null)
|
|
continue;
|
|
|
|
t = GetTypeFromName (ea.EditorTypeName);
|
|
if (t != null && t.IsSubclassOf(editorBaseType))
|
|
break;
|
|
}
|
|
}
|
|
|
|
object editor = null;
|
|
if (t != null)
|
|
editor = CreateInstance (t);
|
|
if (editor == null)
|
|
editor = TypeDescriptor.GetEditor (PropertyType, editorBaseType);
|
|
return editor;
|
|
}
|
|
|
|
protected Type GetTypeFromName (string typeName)
|
|
{
|
|
if (typeName == null || ComponentType == null || typeName.Trim ().Length == 0)
|
|
return null;
|
|
|
|
Type type = Type.GetType (typeName);
|
|
if (type == null) {
|
|
// Try to strip the type typeName only
|
|
int index = typeName.IndexOf (",");
|
|
if (index != -1)
|
|
typeName = typeName.Substring (0, index);
|
|
type = ComponentType.Assembly.GetType (typeName);
|
|
}
|
|
return type;
|
|
}
|
|
}
|
|
}
|