Silverlight 3 PropertyGrid Development Progress


There was no information about Silverlight version of the PropertyGrid control for some period. I would like to leak some information towards the current development progress as well as highlight some of the most remarkable features.

Multiple layouts support

Silverlight PropertyGrid will support at least Alphabetical and Categorized layouts out-of-box. There will be a possibility to write your own layouts with least amount of efforts possible.

Here’s how the the “Categorized” one looks like and defined in XAML:

SPG01

SPG02

“Categorized” layout will be the default one. This means that you won’t need defining anything if “Categorized” behavior is those you expect to have by default.

Note that control will support “Description Box” similar to native Windows Forms PropertyGrid control.

Here’s how the “Alphabetical” layout looks like and defined in XAML:

SPG03

SPG04

Both POCO (Plain Old CLR Objects) and Dependency objects are to be supported. Here’s the Button control bound to PropertyGrid:

SPG05

Property Filtering feature will provide exactly the same functionality Microsoft Expression Blend’s PropertyGrid control gives. It will be possible to filter out properties according to their names and types:

SPG06

SPG07

After Silverlight 3 went RTM the Silverlight PropertyGrid development progress went rapid and smooth and hopefully the control will be available very soon.

More news are coming soon…

Reflection Limitation in .NET 3.5/4.0


Recently a colleague of mine pointed to a strange behavior in .NET Reflection  that pushed me doing a lot of additional investigations and finding out a very serious limitation that might raise a lot of issues if not being taken into account.

When you declare property as “virtual” beware that custom attributes won’t be fetched for the derived one if the property is being overrided.

This can be easily tested. First you need creating two custom attributes that will target two cases: virtual property and virtual method.

  [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  public class MyPropertyAttribute : Attribute
  {
  }

  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  public class MyMethodAttribute : Attribute
  {
  }

Now you can create two classes: “BaseClass” that will contain a single virtual property and single virtual method and “DerivedClass” that will override both members.

 public class BaseClass
  {
    private string _PropertyVirtual;

    [MyProperty]
    public virtual string PropertyVirtual
    {
      get { return _PropertyVirtual; }
      set { _PropertyVirtual = value; }
    }

    [MyMethod]
    public virtual void MethodVirtual()
    {
    }
  }

  public class DerivedClass : BaseClass
  {
    public override string PropertyVirtual
    {
      get { return base.PropertyVirtual; }
      set { base.PropertyVirtual = value; }
    }

    public override void MethodVirtual()
    {
      base.MethodVirtual();
    }
  }

The problem starts when you try fetching custom attributes for “PropertyVirtual” from within a DerivedClass because you will never get them using PropertyInfo.GetCustomAttributes method call. Here’s a sample Console Application to ensure the limitation is alive:

  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Checking virtual property attributes:\r\n");

      Console.WriteLine(
        "BaseClass.PropertyVirtual attributes count: {0}",
        typeof(BaseClass).GetProperty("PropertyVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        typeof(DerivedClass).GetProperty("PropertyVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine("\r\nChecking virtual method attributes:\r\n");

      Console.WriteLine(
        "BaseClass.MethodVirtual attributes count: {0}",
        typeof(BaseClass).GetMethod("MethodVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine(
        "DerivedClass.MethodVirtual attributes count: {0}",
        typeof(DerivedClass).GetMethod("MethodVirtual").GetCustomAttributes(true).Length);

      Console.ReadLine();
    }

Upon running this sample you should see the following results:


Checking virtual property attributes:

BaseClass.PropertyVirtual attributes count: 1
DerivedClass.PropertyVirtual attributes count: 0

Checking virtual method attributes:

BaseClass.MethodVirtual attributes count: 1
DerivedClass.MethodVirtual attributes cound: 1

As you can ensure there are no custom attributes returned for overrided virtual property while the expected result is fetched for overrided virtual method.

You can easily find what is happening under the hood if switching to MSIL representation of the classes coded above. Here’s how the “BaseClass” attribute usage looks like:

Reflection Issue 1

As you can see on the IL level “MethodVirtual” declares “MyMethodAttribute” instance right within its own body. The same goes for “PropertyVirtual” – a getter, a setter and attribute declaration.

However both members look like the following when derived:

Reflection Issue 2

While “MethodVirtual” still refers to “base.MethodVirtual” and theoretically can invoke attribute declaration,

note that the following overriding will still work for methods:

  public class DerivedClass : BaseClass
  {
    public override string PropertyVirtual
    {
      get { return base.PropertyVirtual; }
      set { base.PropertyVirtual = value; }
    }

    public override void MethodVirtual()
    {
      //base.MethodVirtual();
    }
  }

“PropertyVirtual” is no longer related to a base implementation. We have a completely new property definition that is wired with base getter and setter. But no custom attribute declaration!

This means that the default code written for MemberInfo class won’t be able fetching anything except empty object array.

There are two workarounds I found that help switching to another MS developer(s) work, custom attribute fetching seems to be completely different in the following approaches: TypeDescriptor and old-fashioned Attribute class.

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        Attribute.GetCustomAttributes(typeof(DerivedClass).GetProperty("PropertyVirtual"), typeof(MyPropertyAttribute)).Length);

The code above will be able to fetch and display custom attributes for a virtual property. Same can be achieved by means of property descriptors:

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        TypeDescriptor.GetProperties(typeof(DerivedClass))["PropertyVirtual"].Attributes[typeof(MyPropertyAttribute)] != null);

However the last one will have a great performance overhead in comparison with the “Attribute.GetCustomAttributes” usage.

I’ve tested the same issue with .NET 4.0 (beta 2) and it is still there. I really hope this article will help you detecting problems with your software and eliminating issues related to this very case.

You can find the source code for this article here: MetadataIssue