In the previous post we discussed how we can use DynamicObject to add dynamically generated properties to our types. This post would continue the discussion but here we are going to discuss ICustomTypeDescriptor to add dynamically generated properties. We will also discuss how we can use these properties for WPF Binding. In the last part of our discussion we will be adding the missing bit to support change notifications for these properties.
System.ComponentModel has a default implementation of ICustomTypeDescriptor. This provides the interface implementation requirements in the form of virtual methods which can be overridden in your custom type. We will be using this implementation as part of our discussion. Basically the following methods from the interface do all the magic. We can provide implementation of these methods to introduce our custom properties in order to fake the client that the type already has these properties.
This is also more to do with WPF Binding System. If the DataContext implements ICustomTypeDescriptor then WPF Binding system uses the Type Descriptor instead of relying on reflection. From msdn, this discussion is very useful to learn how binding references are resolved.
http://msdn.microsoft.com/en-us/library/bb613546.aspx
Both of the overloads of GetProperties() methods return PropertyDescriptorCollection. It is a collection of PropertyDescriptor. Overriding these methods and adding further items to the collection can give the impression to the WPF Binding system of having these properties by the type itself. Let's provide a descriptor inheriting from PropertyDescriptor.
In the above property descriptor, please look at GetValue and SetValue methods. The type is holding a field called propertyValue. These methods operate on this field. We don't need these methods for working with WPF Binding system and need them to work with the additional properties in our code. Let's use this descriptor to create a Type implementing ICustomTypeDescriptor. We are maintaining an internal collection _myProperties to hold the additional properties which are not provided by the type itself. This would create perception of dynamically generated properties. An additional method, called AddProperty, is provided to add an item to the collection. The method is generic to support a property with any supported type. The type is also implementing INotifyPropertyChanged interface providing change propagation support. This would raise familiar PropertyChanged event when a value is changed using SetValue method.
Now let's use this type and introduce a new type called StudentViewModel. It maintains a property called FirstName. Now here is the intersting part. We are adding another property LastName using AddProperty method of the base type ViewModelBase.
Similarly, we add a new type called MainViewModel. Here also we are adding a property called MainTitle. We are setting the value of this property as "Main App Window". It is maintaining a collection holding a collection of StudentViewModel. Here we are adding members to the collection. We are setting the property of FirstName directly. We are setting the other property LastName using SetPropertyValue method. Another property SelectedStudent is provided to hold the currently selected student.
Now let's use these view models for WPF Binding. We are using MainViewModel as the DataContext of MainWindow. The view mainly has a ListBox and DataGrid to show items from Students collection in the DataContext. There is no difference in the use of FirstName and LastName properties from StudentViewModel even when LastName is being dynamically generated. You can also notice MainTitle being used for App banner.
Since the basic setup is done. Now let's run the application now. We should see the following display:
Supporting Change Notifications
This looks perfect but this has one limitation. This doesn't support change notifications for newly added properties. Since we are using PropertyDescritptor to add dynamic properties, we can easily add this behavior using OnValueChanged from the type. We first need to update the ViewModelBase so that whenever a property is added, we add the ValueChanged to the property descriptor and call OnPropertyChanged from ViewModelBase similary to the existing properties from the inheriting types.
Next we need to add the support in the inheriting PropertyDesriptor type i.e. CustomPropertyDescriptor. This would cause the ValueChanged to be used when SetValue method is called. In turn, PropertyChanged from ViewModelBase would be raised for the same property.
Download
Showing posts with label dynamic. Show all posts
Showing posts with label dynamic. Show all posts
Saturday, September 29, 2012
Dynamically Generated Properties using CustomTypeDescriptor for WPF Binding
Tuesday, May 29, 2012
C# Generics & Arithmetic Operators
In this post we will be discussing using arithmetic operators with C# Generics. Basically C# does static type checking for operators. If compiler cannot determine the actual types it is being applied to, then it results in an error stating that the operator cannot be applied for the type. In the case of generics, since the type is not known, it cannot apply the relevant operator to the expression. In the following, we are using an arithmetic operator '+' to an instance of a type argument and you can see that the compiler doesn't seem to like it.
In the following discussion, we would try to find a solution so that we could use the arithmetic operators in this case.
Let's introduce a generic interface ICalculator<T>. It behaves like a simple calculator and exposes Add, Subtract, Multiply and Divide on the arguments. The type of argument is the same as the type argument of the generic interface.
The simplest implementation of the interface can be as follows:
This is definitely not a production quality code as there is no error checking. But this minimizes the noise keeping focus on the topic under discussion. Now let's try to build the code. As expected compiler doesn't seem to like these arithmetic operators applied to operands of type as Type Arguments. And the compiler is right. It can not do static type checking of these operators as the actual type is not known at compile time.
As discussed in the previous post, generics support various constraints. Based on these constraints, the compiler allows the type arguments to be used in a certain way. The list of constraints can be found here: [http://msdn.microsoft.com/en-us/library/d5x73970%28v=vs.100%29]. There is no such constraint where we could specify that "T" is a numeric type. The compiler shouldn't have any issues in that case as the arithmetic operators can be used with numeric types. The other problem is that even if we were able to specify any such constraint, there is no super type that all of these numeric types inherit from. They are not even reference types that they support inheritence.
One argument would be to avoid using the Generics altogether and provide the Calculator implementation using concrete type. But this would really be cumbersome to implement separate type for each numeric type. Please don't hit me to say that :)
Basically we are not focusing on the main issue when try to find the solution. Static Type checking for operators is the main issue. That is why we are not able to use these operators with these operands. So, the solution could be provided by using "dynamic". Using dynamic would create an expression tree for the expression which would be resolved at runtime. Please refer to this post where we have discussed how DLR uses expresion trees [http://www.shujaat.net/2012/05/expression-trees-part-i.html]. Let's update the Calculator implementation as follows:
Now the code should build successfully. We can use the calculator as follows:
Since there is no type checking at compile time, we can run into issues like these when runtime cannot find the operator overloaded for any type used as type argument.
But this is a general issue possible with use of dynamic feature which can be addressed through various checks with the use of dynamic. There is already enough material on this already.
Download Code:
In the following discussion, we would try to find a solution so that we could use the arithmetic operators in this case.
Let's introduce a generic interface ICalculator<T>. It behaves like a simple calculator and exposes Add, Subtract, Multiply and Divide on the arguments. The type of argument is the same as the type argument of the generic interface.
The simplest implementation of the interface can be as follows:
This is definitely not a production quality code as there is no error checking. But this minimizes the noise keeping focus on the topic under discussion. Now let's try to build the code. As expected compiler doesn't seem to like these arithmetic operators applied to operands of type as Type Arguments. And the compiler is right. It can not do static type checking of these operators as the actual type is not known at compile time.
As discussed in the previous post, generics support various constraints. Based on these constraints, the compiler allows the type arguments to be used in a certain way. The list of constraints can be found here: [http://msdn.microsoft.com/en-us/library/d5x73970%28v=vs.100%29]. There is no such constraint where we could specify that "T" is a numeric type. The compiler shouldn't have any issues in that case as the arithmetic operators can be used with numeric types. The other problem is that even if we were able to specify any such constraint, there is no super type that all of these numeric types inherit from. They are not even reference types that they support inheritence.
One argument would be to avoid using the Generics altogether and provide the Calculator implementation using concrete type. But this would really be cumbersome to implement separate type for each numeric type. Please don't hit me to say that :)
Basically we are not focusing on the main issue when try to find the solution. Static Type checking for operators is the main issue. That is why we are not able to use these operators with these operands. So, the solution could be provided by using "dynamic". Using dynamic would create an expression tree for the expression which would be resolved at runtime. Please refer to this post where we have discussed how DLR uses expresion trees [http://www.shujaat.net/2012/05/expression-trees-part-i.html]. Let's update the Calculator implementation as follows:
Now the code should build successfully. We can use the calculator as follows:
Since there is no type checking at compile time, we can run into issues like these when runtime cannot find the operator overloaded for any type used as type argument.
But this is a general issue possible with use of dynamic feature which can be addressed through various checks with the use of dynamic. There is already enough material on this already.
Download Code:
Labels:
.net 4.0,
.net framework,
Arithmetic Operators,
C#,
dynamic,
Generics,
Integral arithmetic
Subscribe to:
Posts (Atom)



