WPF ListView as a DataGrid – Part 3
- by psheriff
I have had a lot of great feedback on the blog post about turning the ListView into a DataGrid by creating GridViewColumn objects on the fly. So, in the last 2 parts, I showed a couple of different methods for accomplishing this. Let’s now look at one more and that is use Reflection to extract the properties from a Product, Customer, or Employee object to create the columns. Yes, Reflection is a slower approach, but you could create the columns one time then cache the View object for re-use. Another potential drawback is you may have columns in your object that you do not wish to display on your ListView. But, just because so many people asked, here is how to accomplish this using Reflection.
Figure 1: Use Reflection to create GridViewColumns.
Using Reflection to gather property names is actually quite simple. First you need to pass any type (Product, Customer, Employee, etc.) to a method like I did in my last two blog posts on this subject. Below is the method that I created in the WPFListViewCommon class that now uses reflection.
C#public static GridView CreateGridViewColumns(Type anyType){ // Create the GridView GridView gv = new GridView(); GridViewColumn gvc;
// Get the public properties. PropertyInfo[] propInfo = anyType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo item in propInfo) { gvc = new GridViewColumn(); gvc.DisplayMemberBinding = new Binding(item.Name); gvc.Header = item.Name; gvc.Width = Double.NaN; gv.Columns.Add(gvc); }
return gv;}
VB.NETPublic Shared Function CreateGridViewColumns( _ ByVal anyType As Type) As GridView ' Create the GridView Dim gv As New GridView() Dim gvc As GridViewColumn
' Get the public properties. Dim propInfo As PropertyInfo() = _ anyType.GetProperties(BindingFlags.Public Or _ BindingFlags.Instance)
For Each item As PropertyInfo In propInfo gvc = New GridViewColumn() gvc.DisplayMemberBinding = New Binding(item.Name) gvc.Header = item.Name gvc.Width = [Double].NaN gv.Columns.Add(gvc) Next
Return gvEnd Function
The key to using Relection is using the GetProperties method on the type you pass in. When you pass in a Product object as Type, you can now use the GetProperties method and specify, via flags, which properties you wish to return. In the code that I wrote, I am just retrieving the Public properties and only those that are Instance properties. I do not want any static/Shared properties or private properties.
GetProperties returns an array of PropertyInfo objects. You can loop through this array and build your GridViewColumn objects by reading the Name property from the PropertyInfo object.
Build the Product Screen
To populate the ListView shown in Figure 1, you might write code like the following:
C#private void CollectionSample(){ Product prod = new Product();
// Setup the GridView Columns lstData.View = WPFListViewCommon.CreateGridViewColumns(typeOf(Product)); lstData.DataContext = prod.GetProducts();}
VB.NETPrivate Sub CollectionSample() Dim prod As New Product()
' Setup the GridView Columns lstData.View = WPFListViewCommon.CreateGridViewColumns( _ GetType(Product)) lstData.DataContext = prod.GetProducts()End Sub
All you need to do now is to pass in a Type object from your Product class that you can get by using the typeOf() function in C# or the GetType() function in VB. That’s all there is to it!
Summary
There are so many different ways to approach the same problem in programming. That is what makes programming so much fun! In this blog post I showed you how to create ListView columns on the fly using Reflection. This gives you a lot of flexibility without having to write extra code as was done previously.
NOTE: You can download the complete sample code (in both VB and C#) at my website. http://www.pdsa.com/downloads. Choose Tips & Tricks, then "WPF ListView as a DataGrid – Part 3" from the drop-down.
Good Luck with your Coding,Paul Sheriff
** SPECIAL OFFER FOR MY BLOG READERS **Visit http://www.pdsa.com/Event/Blog for a free eBook on "Fundamentals of N-Tier".