Hello,
The problem i encoutered :
I have a property named Tabs which i'd like in some condition to set it to read only, the Tabs propertyreturn value is: TabCollectionAdpator a collection, the problem is that its the property never got readonly.
I check my architecture on other property (ret value is string) and its work fine, What to do , i suspect that because the Tabs property return value is collection and use by default the collection converter so it cause the problem, So How can i control the behavior, solve the issue.
Here the code :
///
<summary>
/// Adaptor for an TabCollection object
/// </summary>
public class TabCollectionAdpator : ArrayList,
IList{
...
}
public
class MainObjectAdaptor : ICustomTypeDescriptor
{
#region
Data members
privateMainObjectConfig refObject = null;
private TabCollectionAdpator m_tabsAdaptor = null;
#endregion
public
MainObjectAdaptor () : base()
{
m_ReadOnlyPropertyDescriptor =
new ReadOnlyPropertyDescriptor(
TypeDescriptor.GetProperties(this)["Tabs"]);
refObject =
new Client.ConfigurationsRepository.MainObjectConfig ();
...
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Description(Consts.PropertyDescriptions.TABS)]
public TabCollectionAdpator Tabs{
get { return m_tabsAdaptor; }
set{
refObject.Tabs.Clear(); // The ref object si the real object wrap by the adaptor.
TabCollection tbs = value.AdoptedObject as TabCollection;
if (tbs == null)
{
throw new Exception(
string.Format(Consts.Messages.ADOPTED_OBJECT_MISMATCH_TYPE,
"Tabs"));
}
foreach (Client.ConfigurationsRepository.Tab tb in tbs) {
refObject.Tabs.TabCollection.Add(tb);
}
OnPropertyChanged("Tabs");
}
}
#region
ICustomTypeDescriptor interface
///<summary>
///Returns a collection of custom attributes for this instance of a component.
///</summary>
///
///<returns>
///An <see cref="T:System.ComponentModel.AttributeCollection"></see> containing the attributes for this object.
///</returns>
///
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}
///<summary>
///Returns the class name of this instance of a component.
///</summary>
///
///<returns>
///The class name of the object, or null if the class does not have a name.
///</returns>
///
public string GetClassName()
{
return TypeDescriptor.GetClassName(this , true);
}
///<summary>
///Returns the name of this instance of a component.
///</summary>
///
///<returns>
///The name of the object, or null if the object does not have a name.
///</returns>
///
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}
///<summary>
///Returns a type converter for this instance of a component.
///</summary>
///
///<returns>
///A <see cref="T:System.ComponentModel.TypeConverter"></see> that is the converter for this object, or null if there is no <see cref="T:System.ComponentModel.TypeConverter"></see> for this object.
///</returns>
///
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
///<summary>
///Returns the default event for this instance of a component.
///</summary>
///
///<returns>
///An <see cref="T:System.ComponentModel.EventDescriptor"></see> that represents the default event for this object, or null if this object does not have events.
///</returns>
///
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}
///<summary>
///Returns the default property for this instance of a component.
///</summary>
///
///<returns>
///A <see cref="T:System.ComponentModel.PropertyDescriptor"></see> that represents the default property for this object, or null if this object does not have properties.
///</returns>
///
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(this, true);
}
///<summary>
///Returns an editor of the specified type for this instance of a component.
///</summary>
///
///<returns>
///An <see cref="T:System.Object"></see> of the specified type that is the editor for this object, or null if the editor cannot be found.
///</returns>
///
///<param name="editorBaseType">A <see cref="T:System.Type"></see> that represents the editor for this object. </param>
public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
///<summary>
///Returns the events for this instance of a component.
///</summary>
///
///<returns>
///An <see cref="T:System.ComponentModel.EventDescriptorCollection"></see> that represents the events for this component instance.
///</returns>
///
public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}
///<summary>
///Returns the events for this instance of a component using the specified attribute array as a filter.
///</summary>
///
///<returns>
///An <see cref="T:System.ComponentModel.EventDescriptorCollection"></see> that represents the filtered events for this component instance.
///</returns>
///
///<param name="attributes">An array of type <see cref="T:System.Attribute"></see> that is used as a filter. </param>
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}
///<summary>
///Returns the properties for this instance of a component.
///</summary>
///
///<returns>
///A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"></see> that represents the properties for this component instance.
///</returns>
///
public PropertyDescriptorCollection GetProperties()
{
return TypeDescriptor.GetProperties(this, true);
}
///<summary>
///Returns the properties for this instance of a component using the attribute array as a filter.
///</summary>
///
///<returns>
///A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"></see> that represents the filtered properties for this component instance.
///</returns>
///
///<param name="attributes">An array of type <see cref="T:System.Attribute"></see> that is used as a filter. </param>
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(GetType() , attributes);
List<PropertyDescriptor> propList = new List<PropertyDescriptor>();
foreach (PropertyDescriptor prop in properties)
{
if (prop.Name == "Tabs")
propList.Add(m_ReadOnlyPropertyDescriptor);
else
propList.Add(prop);
}
return new PropertyDescriptorCollection(propList.ToArray(),false);
}
private static ReadOnlyPropertyDescriptor m_ReadOnlyPropertyDescriptor;
///<summary>
///Returns an object that contains the property described by the specified property descriptor.
///</summary>
///
///<returns>
///An <see cref="T:System.Object"></see> that represents the owner of the specified property.
///</returns>
///
///<param name="pd">A <see cref="T:System.ComponentModel.PropertyDescriptor"></see> that represents the property whose owner is to be found. </param>
public object GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
#endregion
}
public
class ReadOnlyPropertyDescriptor : SpecificPropertyDescriptor
{
public ReadOnlyPropertyDescriptor(PropertyDescriptor i_root) : base(i_root)
{
}
///<summary>
///When overridden in a derived class, gets a value indicating whether this property is read-only.
///</summary>
///
///<returns>
///true if the property is read-only; otherwise, false.
///</returns>
///
public override bool IsReadOnly
{
get { return true; }
}
}
public
class SpecificPropertyDescriptor : PropertyDescriptor
{
private readonly PropertyDescriptor m_propertyRoot;
protected PropertyDescriptor PropertyRoot
{
get { return m_propertyRoot; }
}
protected SpecificPropertyDescriptor(PropertyDescriptor root)
:
base(root)
{
m_propertyRoot = root;
}
public override void AddValueChanged(object component,
EventHandler
handler)
{
PropertyRoot.AddValueChanged(component, handler);
}
public override AttributeCollection Attributes
{
get { return PropertyRoot.Attributes; }
}
public override bool CanResetValue(object component)
{
return PropertyRoot.CanResetValue(component);
}
public override string Category
{
get { return PropertyRoot.Category; }
}
public override Type ComponentType
{
get { return PropertyRoot.ComponentType; }
}
public override TypeConverter Converter
{
get { return PropertyRoot.Converter; }
}
public override string Description
{
get { return PropertyRoot.Description; }
}
public override bool DesignTimeOnly
{
get { return PropertyRoot.DesignTimeOnly; }
}
public override string DisplayName
{
get { return PropertyRoot.DisplayName; }
}
public override bool Equals(object obj)
{
return PropertyRoot.Equals(obj);
}
public override PropertyDescriptorCollection
GetChildProperties(
object instance,
Attribute[] filter)
{
return PropertyRoot.GetChildProperties(instance, filter);
}
public override object GetEditor(Type editorBaseType)
{
return PropertyRoot.GetEditor(editorBaseType);
}
public override int GetHashCode()
{
return PropertyRoot.GetHashCode();
}
public override object GetValue(object component)
{
return PropertyRoot.GetValue(component);
}
public override bool IsBrowsable
{
get { return PropertyRoot.IsBrowsable; }
}
public override bool IsLocalizable
{
get { return PropertyRoot.IsLocalizable; }
}
public override bool IsReadOnly
{
get { return PropertyRoot.IsReadOnly; }
}
public override string Name
{
get { return PropertyRoot.Name; }
}
public override Type PropertyType
{
get { return PropertyRoot.PropertyType; }
}
public override void RemoveValueChanged(object component,
EventHandler handler)
{
PropertyRoot.RemoveValueChanged(component, handler);
}
public override void ResetValue(object component)
{
PropertyRoot.ResetValue(component);
}
public override void SetValue(object component,
object value)
{
PropertyRoot.SetValue(component, value);
}
public override bool ShouldSerializeValue(object component)
{
return PropertyRoot.ShouldSerializeValue(component);
}
public override bool SupportsChangeEvents
{
get { return PropertyRoot.SupportsChangeEvents; }
}
public override string ToString()
{
return PropertyRoot.ToString();
}
}