//
// System.ComponentModel.MemberDescriptor.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
//
//
// 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;
using System.ComponentModel.Design;
using System.Globalization;
namespace System.ComponentModel{
[ComVisible (true)]
public abstract class MemberDescriptor
{
private string name;
private Attribute [] attrs; // only the attributes supplied in the ctor
private AttributeCollection attrCollection;
private static IComparer default_comparer;
protected MemberDescriptor (string name, Attribute [] attrs)
{
this.name = name;
this.attrs = attrs;
}
protected MemberDescriptor (MemberDescriptor reference, Attribute [] attrs)
{
name = reference.name;
this.attrs = attrs;
}
protected MemberDescriptor (string name)
{
this.name = name;
}
protected MemberDescriptor (MemberDescriptor reference)
{
name = reference.name;
attrs = reference.AttributeArray;
}
protected virtual Attribute [] AttributeArray {
get {
ArrayList list = new ArrayList ();
if (attrs != null)
list.AddRange (attrs);
FillAttributes (list);
// For duplicate attributes, the last one added to the list is kept.
Hashtable attributes = new Hashtable ();
foreach (Attribute attribute in list)
attributes[attribute.TypeId] = attribute;
Attribute[] attributesArray = new Attribute[attributes.Values.Count];
attributes.Values.CopyTo (attributesArray, 0);
return attributesArray;
}
set {
attrs = value;
}
}
protected virtual void FillAttributes(System.Collections.IList attributeList)
{
// to be overriden
}
public virtual AttributeCollection Attributes {
get {
if (attrCollection == null)
attrCollection = CreateAttributeCollection ();
return attrCollection;
}
}
protected virtual AttributeCollection CreateAttributeCollection ()
{
return new AttributeCollection (AttributeArray);
}
public virtual string Category {
get {
return ((CategoryAttribute) Attributes [typeof (CategoryAttribute)]).Category;
}
}
public virtual string Description {
get {
foreach (Attribute attr in AttributeArray)
if (attr is DescriptionAttribute)
return ((DescriptionAttribute) attr).Description;
return string.Empty;
}
}
public virtual bool DesignTimeOnly {
get {
foreach (Attribute attr in AttributeArray)
if (attr is DesignOnlyAttribute)
return ((DesignOnlyAttribute) attr).IsDesignOnly;
return false;
}
}
public virtual string DisplayName {
get {
#if NET_2_0
foreach (Attribute attr in AttributeArray)
if (attr is DisplayNameAttribute)
return ((DisplayNameAttribute) attr).DisplayName;
#endif
return name;
}
}
public virtual string Name {
get {
return name;
}
}
public virtual bool IsBrowsable {
get {
foreach (Attribute attr in AttributeArray)
if (attr is BrowsableAttribute)
return ((BrowsableAttribute) attr).Browsable;
return true;
}
}
protected virtual int NameHashCode {
get {
return name.GetHashCode ();
}
}
public override int GetHashCode ()
{
return base.GetHashCode ();
}
public override bool Equals (object obj)
{
MemberDescriptor other = obj as MemberDescriptor;
if (other == null)
return false;
return other.name == name;
}
protected static ISite GetSite (object component)
{
if (component is Component)
return ((Component) component).Site;
else
return null;
}
#if NET_2_0
[Obsolete ("Use GetInvocationTarget")]
#endif
protected static object GetInvokee (Type componentClass, object component)
{
if (component is IComponent) {
ISite site = ((IComponent) component).Site;
if (site != null && site.DesignMode) {
IDesignerHost host = site.GetService (typeof (IDesignerHost)) as IDesignerHost;
if (host != null) {
IDesigner designer = host.GetDesigner ((IComponent) component);
if (designer != null && componentClass.IsInstanceOfType (designer)) {
component = designer;
}
}
}
}
return component;
}
#if NET_2_0
protected virtual object GetInvocationTarget (Type type, object instance)
{
if (type == null)
throw new ArgumentNullException ("type");
if (instance == null)
throw new ArgumentNullException ("instance");
return GetInvokee (type, instance);
}
#endif
protected static MethodInfo FindMethod(Type componentClass, string name, Type[] args, Type returnType)
{
return FindMethod (componentClass, name, args, returnType, true);
}
protected static MethodInfo FindMethod(Type componentClass, string name, Type[] args, Type returnType, bool publicOnly)
{
BindingFlags bf;
if (publicOnly == true)
bf = BindingFlags.Public;
else
bf = BindingFlags.NonPublic | BindingFlags.Public;
// FIXME returnType is not taken into account. AFAIK methods are not allowed to only
// differ by return type anyway
return componentClass.GetMethod (name, bf, null, CallingConventions.Any, args, null);
}
internal static IComparer DefaultComparer {
get {
if (default_comparer == null)
default_comparer = new MemberDescriptorComparer ();
return default_comparer;
}
}
private class MemberDescriptorComparer : IComparer
{
public int Compare (object x, object y)
{
return String.Compare (((MemberDescriptor)x).Name, ((MemberDescriptor)y).Name,
false, CultureInfo.InvariantCulture);
}
}
}
}
|