ICustomTypeDescriptor throws argumentexception when implemented

793 views Asked by At

I want to exclude the Property MiddleName from the browseable Properties in my PropertyGrid.

When I hang around the interface ICustomTypeDescriptor on my Person class I get this exception while starting my app.

What do I wrong?

System.ArgumentException: Can not bind to the property or column TestNamefür on the DataSource. Parametername: dataMember bei System.Windows.Forms.BindToObject.CheckBinding() bei System.Windows.Forms.Binding.SetListManager(BindingManagerBase bindingManagerBase) bei System.Windows.Forms.ListManagerBindingsCollection.AddCore(Binding dataBinding)

public class Person : ICustomTypeDescriptor
{
    public string TestName { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }

    AttributeCollection ICustomTypeDescriptor.GetAttributes()
    {
      return TypeDescriptor.GetAttributes(this, true);
    }
    string ICustomTypeDescriptor.GetClassName()
    {
      return TypeDescriptor.GetClassName(this, true);
    }
    string ICustomTypeDescriptor.GetComponentName()
    {
      return TypeDescriptor.GetComponentName(this, true);
    }
    TypeConverter ICustomTypeDescriptor.GetConverter()
    {
      return TypeDescriptor.GetConverter(this, true);
    }
    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
    {
      return TypeDescriptor.GetDefaultEvent(this, true);
    }
    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
    {
      return TypeDescriptor.GetDefaultProperty(this, true);
    }
    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
    {
      return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }
    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
    {
      return TypeDescriptor.GetEvents(this, attributes, true);
    }
    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
    {
      return TypeDescriptor.GetEvents(this, true);
    }
    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
    {
      Debug.Print("GetProperties()");
      Print("Attributes is {0}null", attributes == null ? "" : "not ");
      PropertyDescriptorCollection origCol = TypeDescriptor.GetProperties(this, attributes, true);
      bool wantBrowsable = attributes.Contains<Attribute>(new BrowsableAttribute(true));
      Debug.Print("Wants Browsable: {0}", wantBrowsable);
      List<PropertyDescriptor> newCol = new List<PropertyDescriptor>();
      foreach (PropertyDescriptor pd in origCol)
      {
        System.Diagnostics.Debug.Print("Property Name: {0}", pd.Name);
        if (pd.Name != "MiddleName")
        {
          System.Diagnostics.Debug.Print("Property {0} is included.", pd.Name);
          newCol.Add(pd);
        }
      }
      return new PropertyDescriptorCollection(newCol.ToArray());
    }
    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
    {
      return ((ICustomTypeDescriptor)this).GetProperties(null);
    }
    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
    {
      return this;
    }
}

UPDATE + SOLUTION:

Properties which are marked with Browseable(false) can not be bound! so I did this:

Why Browsable attribute makes property not bindable?

The last solution from Marc Gravell worked like a breath!

1

There are 1 answers

4
digEmAll On

I tested your code seems to work in my test. Maybe we need more of your code to understand what's the problem.

Anyway, if your only purpose is just to hide MiddleName property from Propertygrid, why don't simply put [Browsable(false) attribute on that property, instead of implement an ICustomTypeDescriptor?

It would save you from a lot of code...

EDIT:

I mean, a code like this must work:

public class Person
{
    public string TestName { get; set; }

    public string FirstName { get; set; }

    [Browsable(false)]
    public string MiddleName { get; set; }

    public string LastName { get; set; }
}

and should correctly hide MiddleName property from property grid...