Microsoft Communities

Welcome to WindowsClient.net | Sign in | Join

Here are some frequently asked questions about Windows Forms and their answers.

Windows Forms FAQs

How do I display property names in the Property grid that are different from the actual property names in the class?

You can do this but it's not as simple as using an attribute. If you want to modify the property names for your component, you have to interact with the reflection mechanism that the grid is using by implementing ICustomTypeDescriptor. The grid operates on objects called PropertyDescriptors with are the Framework's generic wrapper for a property, where reflection is a specific implementation. So what ICustomTypeDescriptor allows you to do is to have your object asked for it's properties rather than than the default system, which is reflection.

You then write your own derived version of PropertyDescriptor (an abstract class in System.ComponentModel) and return your property descriptors instead of the ones that come back from the TypeDescriptor... so some of the implementation would look something like this.

public class FriendlyNamePropertyDescriptor : PropertyDescriptor 
{ 
  private PropertyDescriptor baseProp; 
  private string friendlyName; 

  public FriendlyNamePropertyDescriptor( PropertyDescriptor baseProp, Attribute[] filter ) 
    : base( baseProp ) 
  { 
    this.baseProp = baseProp; 
  } 
           
  public override string Name 
  { get { return baseProp.Name; } }
 
  public override string DisplayName // replace with code to return a friendly name 
  { get { return GetFriendlyname( baseProp.Name ); }  }
 
  public override bool IsReadOnly 
  { get { return baseProp.IsReadOnly; } } 
           
  public override bool CanResetValue( object component ) 
  { return baseProp.CanResetValue( component ); } 
           
  public override Type ComponentType 
  { get { return baseProp.ComponentType; } }
 
  public override object GetValue( object component ) 
  { return baseProp.GetValue( component ); }

  public override Type PropertyType 
  { get { return baseProp.PropertyType; } }
 
  public override void ResetValue( object component ) 
  { baseProp.ResetValue( component ); }
 
  public override void SetValue( object component, object Value ) 
  { baseProp.SetValue( component, Value ); }
 
  public override bool ShouldSerializeValue( object component ) 
  { return baseProp.ShouldSerializeValue( component ); } 
}

A custom class:

public class CustomClass : ICustomTypeDescriptor 
{ 
  PropertyDescriptorCollection 
    ICustomTypeDescriptor.GetProperties( Attribute[] filter ) 
  { 
    PropertyDescriptorCollection baseProps =
      TypeDescriptor.GetProperties( GetType(), filter ); 
    
    // notice we use the type here so we don't recurse 
    PropertyDescriptor[] newProps = new PropertyDescriptor[ baseProps.Count ]; 
    for ( int i = 0; i < baseProps.Count; ++i ) 
    { 
      newProps[ i ] = new FriendlyNamePropertyDescriptor( baseProps[ i ], filter ); 
      string oldname = ((PropertyDescriptor) baseProps[ i ]).DisplayName ; 
      string newname = ((FriendlyNamePropertyDescriptor) newProps[ i ]).DisplayName; 
    } 
    // probably want to cache this... 
    return new PropertyDescriptorCollection( newProps ); 
  }

  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 ); }
 
  EventDescriptorCollection 
    ICustomTypeDescriptor.GetEvents( Attribute[] attributes ) 
  { return TypeDescriptor.GetEvents( this, attributes, true ); } 
  
  EventDescriptorCollection ICustomTypeDescriptor.GetEvents() 
  { return TypeDescriptor.GetEvents( this, true ); }
 
  PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() 
  { return TypeDescriptor.GetDefaultProperty( this, true ); }
 
  PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() 
  { return TypeDescriptor.GetProperties( this, true ); }
 
  object ICustomTypeDescriptor.GetEditor( Type editorBaseType ) 
  { return TypeDescriptor.GetEditor( this, editorBaseType, true ); }
 
  object ICustomTypeDescriptor.GetPropertyOwner( PropertyDescriptor pd ) 
  { return this; }
 
  // the code for CustomClass
  // including the properties to show in the propertygrid ...
}

Shawn Burke, Microsoft, and Rachid El Masoudi



Page view counter