Hey folks.
The past 2 months i was implementing an application using the telerik controls.
Awesome control set by the way. Love them.
But there is a slight disadvantage as i thought. The setup of columns for the RadGridView.
There is the possibility to use
AutoGenerateColumns or just set them up in your
.xaml.
For your information i am using a MVVM implementation. The problem for me, i have views which are basicly the same.
They only differ in some additional columns for the grid.
I have come up that
AutoGenerateColumns is just an awesome feature to give a simple
ViewItem into a list an set the list as ItemsSource, now my columns just show up. Adding some annotations to the properties is just a cool way to give them special behavior.
But what about custom annotations? E.g. disable distinct filters and to so on. Fortunatly
RadGridView supports basic annotations (System.ComponentModel.DataAnnotations) which is good, but not perfect.
To enhance this, i have come up to implement
CustomAttributes.
Here you can see my simple CustomAttribute class:
As you can see i have added an abstract method
UpdateColumn() this method will be implemented in each attribute you like to use.
This is used to updated the column which your own logic. As seen here, a simple
ShowDistinctFilterAttribute:
Now things gettin' serious. We need to intercept the autogenerating of columns.
We need a class derived from
RadGridView. Giving you this:
public
class
BaseGridView<TViewItemType> : RadGridView
{
/// <summary>
/// Raises the AutoGeneratingColumn event.
/// </summary>
protected
override
void
OnAutoGeneratingColumn(GridViewAutoGeneratingColumnEventArgs e)
{
/**
* This method gets overridden to update the autogenerated columns
* with our own custom attributes. The update itself it handled
* in the attribute class itself using the UpdateColumn() method.
*/
// first we need the type of the current viewitem.
var viewItemType =
typeof
(TViewItemType);
// next up we are getting the property
// this property should have some attributes assigned to it.
var property = viewItemType.GetProperty(e.ItemPropertyInfo.Name);
// first off, check if the property even exists
if
(property !=
null
)
{
// now we only get custom attributes of a certain type
// each attribute we want will derive from CustomAttribute class
var attribs = property.GetCustomAttributes(
typeof
(CustomAttribute),
true
);
// check if custom attributes are assigned to the current property
if
(attribs.Any())
{
// iterate through a casted list
// this is needed to get reference to the UpdateColumn() method.
foreach
(var attrib
in
attribs.Cast<CustomAttribute>().ToArray())
{
// update our column
attrib.UpdateColumn(e.Column);
}
}
}
// call base functionality
base
.OnAutoGeneratingColumn(e);
}
}
You might ask why this class is a generic type. Well since we are using reflection to get our custom attributes. We need to now which type our items are using.
RadGridView itself is a bit "well sealed" of getting the datetype of a column item so i come up with this solution. I am skipping the explanation how this code works, i hope the comment lines are enough for this :)
Now you simply need to derive from this
BaseGridView<T> to create the grid you need.
And the
GridViewItem you might want to use with our own attribute:
Now only create a list to set your
ItemsSource
Hope i could help some of you out there :)
Greets.