The holiday season is a time for rich food, the warmth of family and friends, and festive fun and good times. And, if you are like me, you were able to squeeze in some computer time when the kiddies were playing their XBoxes or watching their new DVDs in between sledding and ice skating.
Of course, if you are going to play with technology during the holidays, you might as well play with fun technology. When I wasn't fighting the Lich King, I was working with Devexpress controls for Windows and the web. The Windows controls are part of an application I am helping a friend with, and the web controls because Devexpress put out a new release 8.3. Naturally, I wanted to take Devexpress' new controls for a spin.
One of the most popular web controls is Devexpress' ASPxGridView. To help you explore, I have included several graphics and some code that show you how to use the new filter feature, grid sorting, and grouping, and how to use the XPO Persistent Classes to help you generate your custom entity classes.
The article is a little on the long side, so if you want to go refill your eggnog from whatever's left over, I'll wait. Already back, I see. Good.
Binding Persistent Classes to an ASPxGridView
An entity class is a class that represents a database table, generally. It's not worth being dogmatic about where you get your entity classes. Sometimes, you might roll your own, you might use something like Microsoft's LINQ to SQL, or you can use Devexpress' XPO Persistent Classes. The Express Persistent Classes (XPO) are designed to work with Devexpress' XpoDataSource and controls; if you are creating an application that leverages Devexpress' professional looking controls, the XPO Persistent Classes may be the way to go.
Start by creating a new web site project with Visual Studio 2008. To that project, you need to add an XPO class. XPO classes are code-generated in Visual Studio by selecting Project|Add New Item|Persistent Classes 8.3. The wizard will display a dialog labeled "Generating Persistent Classes for an Existing Database" (see Figure 1). The first step lets you pick the provider and the database connection. After you pick the database, click Next and select the table and the columns (see Figure 2). After you click Finish, the Persistent Classes will code-generate entity classes based on your selections. For the demonstration, select the Northwind Traders database and the Products table.
Figure 1: The XPO Persistent Classes item starts a wizard that will code generate entity classes based on your selections.
Figure 2: For the demo, pick the Northwind Traders Products table and all of the columns.
After you click Finish, the Devexpress' XPO technology will generate the classes and properties that represent the tables and columns you selected. Each source file will have a namespace that reflects the database and a class that reflects the tables.
Listing 1: The code generated from the XPO Persistent Classes item installed when you install Devexpress controls.
Imports System Imports DevExpress.Xpo Namespace northwind Public Class Products Inherits XPLiteObject Dim fProductID As Integer <Key(true)> _ Public Property ProductID() As Integer Get Return fProductID End Get Set(ByVal value As Integer) SetPropertyValue(Of Integer)("ProductID", _ fProductID, value) End Set End Property Dim fProductName As String <Size(40)> _ Public Property ProductName() As String Get Return fProductName End Get Set(ByVal value As String) SetPropertyValue(Of String)("ProductName", fProductName, value) End Set End Property Dim fSupplierID As Integer Public Property SupplierID() As Integer Get Return fSupplierID End Get Set(ByVal value As Integer) SetPropertyValue(Of Integer)("SupplierID", fSupplierID, value) End Set End Property Dim fCategoryID As Integer Public Property CategoryID() As Integer Get Return fCategoryID End Get Set(ByVal value As Integer) SetPropertyValue(Of Integer)("CategoryID", fCategoryID, value) End Set End Property Dim fQuantityPerUnit As String <Size(20)> _ Public Property QuantityPerUnit() As String Get Return fQuantityPerUnit End Get Set(ByVal value As String) SetPropertyValue(Of String)("QuantityPerUnit", fQuantityPerUnit, value) End Set End Property Dim fUnitPrice As Decimal Public Property UnitPrice() As Decimal Get Return fUnitPrice End Get Set(ByVal value As Decimal) SetPropertyValue(Of Decimal)("UnitPrice", fUnitPrice, value) End Set End Property Dim fUnitsInStock As Short Public Property UnitsInStock() As Short Get Return fUnitsInStock End Get Set(ByVal value As Short) SetPropertyValue(Of Short)("UnitsInStock", fUnitsInStock, value) End Set End Property Dim fUnitsOnOrder As Short Public Property UnitsOnOrder() As Short Get Return fUnitsOnOrder End Get Set(ByVal value As Short) SetPropertyValue(Of Short)("UnitsOnOrder", fUnitsOnOrder, value) End Set End Property Dim fReorderLevel As Short Public Property ReorderLevel() As Short Get Return fReorderLevel End Get Set(ByVal value As Short) SetPropertyValue(Of Short)("ReorderLevel", fReorderLevel, value) End Set End Property Dim fDiscontinued As Boolean Public Property Discontinued() As Boolean Get Return fDiscontinued End Get Set(ByVal value As Boolean) SetPropertyValue(Of Boolean)("Discontinued", fDiscontinued, value) End Set End Property Public Sub New(ByVal session As Session) MyBase.New(session) End Sub Public Sub New() MyBase.New(Session.DefaultSession) End Sub Public Overrides Sub AfterConstruction() MyBase.AfterConstruction() End Sub End Class End Namespace
The generated code is straightforward. The class represents the table, and the properties represent the table columns. The setters have a call to a generic SetPropertyValue method that, if I had to guess, I would say it contains a unified dirty-state tracking mechanism. A quick scan of Reflector says it looks like SetPropertyValue checks to see whether the new value is identical to the old value and raises some events and updates the Session's version of the property state.