Introduction
Every year, my family frantically tries to send out holiday cards to family and friends (late). This year, I vowed it would be different. I've recently become acquainted with the DevExpress eXpress Application Framework (XAF) and decided to put it to the test. Even though I do work at DevExpress as a PM over analytics, I really hadn't played with XAF all that much. I have a reason to now.
There is an absurd amount of documentation (see this starting off point) that might be a bit overwhelming so I decided to start with the easiest thing – make the appropriate data structures to see what happens.
Creating the Project
Creating the project is pretty straight forward:
Simply select the Cross-Platform Application template and we are off:
This process will automatically create a couple of projects on our behalf. The portion we will focus on for this tip is the base Module and the Windows project.
Adding Some Code
Our application primarily deals with households and the people within the household. Each household should be able to have one or more members. In XAF, we need to add two Domain Objects in order to represent this type of data: one for a Household
and one for a Person
. To add a domain object, simply right click on the BusinessObjects folder and select add New:
The Domain
Object holds the properties of both the Household
and Person
entities. Given that this code is somewhat tedious, we have added some CodeRush
templates to make this faster.
We can also use CodeRush
to generate the associations between objects:
Here are the two Domain
objects side by side:
Household Domain Object
[DefaultClassOptions, ImageName("BO_Address")]
public class Household : BaseObject
{
public Household(Session session)
: base(session)
{
}
public override void AfterConstruction()
{
base.AfterConstruction();
}
private string _address;
private string _phone;
private string _zip;
private string _state;
private string _city;
private string _name;
public string Name
{
get
{
return _name;
}
set
{
SetPropertyValue("Name", ref _name, value);
}
}
public string Address
{
get
{
return _address;
}
set
{
SetPropertyValue("Address", ref _address, value);
}
}
public string City
{
get
{
return _city;
}
set
{
SetPropertyValue("City", ref _city, value);
}
}
public string State
{
get
{
return _state;
}
set
{
SetPropertyValue("State", ref _state, value);
}
}
public string Zip
{
get
{
return _zip;
}
set
{
SetPropertyValue("Zip", ref _zip, value);
}
}
public string Phone
{
get
{
return _phone;
}
set
{
SetPropertyValue("Phone", ref _phone, value);
}
}
[Association("Household-Members")]
public XPCollection<person> Members
{
get
{
return GetCollection<person>("Members");
}
}
}
Person Domain Object
[DefaultClassOptions, ImageName("BO_Person")]
public class Person : BaseObject
{
public Person(Session session)
: base(session)
{
}
public override void AfterConstruction()
{
base.AfterConstruction();
}
private Household _household;
private DateTime _birthDate;
private string _phone;
private string _cell;
private string _email;
private string _lastName;
private string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
SetPropertyValue("FirstName", ref _firstName, value);
}
}
public string LastName
{
get
{
return _lastName;
}
set
{
SetPropertyValue("LastName", ref _lastName, value);
}
}
public DateTime BirthDate
{
get
{
return _birthDate;
}
set
{
SetPropertyValue("BirthDate", ref _birthDate, value);
}
}
public string Email
{
get
{
return _email;
}
set
{
SetPropertyValue("Email", ref _email, value);
}
}
public string Cell
{
get
{
return _cell;
}
set
{
SetPropertyValue("Cell", ref _cell, value);
}
}
public string Phone
{
get
{
return _phone;
}
set
{
SetPropertyValue("Phone", ref _phone, value);
}
}
[Association("Household-Members")]
public Household Household
{
get
{
return _household;
}
set
{
SetPropertyValue("Household", ref _household, value);
}
}
}
Along with the properties, the only other thing I added on the class was the image properties (this [ImageName("BO_Person")]
) that specified the icon the system should use when presenting the domain classes. Alternatively one could use the model editor to change the icons in a couple of steps.
First, open the model editor:
Then, select the appropriate icon:
The last thing I did was change a couple of options that changed the look, feel, and navigation of the Windows Application (in the Windows Module):
The best part about these types of customizations is that the end user can make the same kinds of changes by running the executable and making the changes themselves:
That is it! Now it's time to run the application.
End Result
After running the program, you (and your users) can further customize the application to suit your needs.
Since the default layout did not really work for me, you can see how I manually made the changes myself to the layout of the application:
After these last few modifications, the end result is a fully functioning application that saves and loads information directly from the database.
When you first run the XAF application, the underlying framework looks at your domain classes to create the corresponding database tables and relationships. By default, the system will try to connect to a default SQLExpress instance of SQL Server and create a database with the name of your application. This can be easily changed by going to WinApplication
designer and changing the corresponding properties of the connection:
Summary
The best part of this whole process is the number of features the framework gives you by default. The process of creating a pure CRUD application based on objects is also very straightforward:
- Think about the domain classes and relationships
- Create the domain classes
- Run the application and customize navigation and appearance
Obviously not every application is as straightforward as creating, reading, and updating plain business objects. In subsequent posts, I want to look at how XAF handles "coming off the rails" so-to-speak. In other words, how easy is it to further customize and extend the application? Stay tuned!
Bonus
At the beginning of the tip, I suggested we create a cross-platform application. Turns out that setting the Web Application as the startup project and running it produces this:
A full web application that is the functional equivalent of the Windows Application is produced without any additional effort.
This might be less stressful holidays after all.
Yeah... I wish I knew about this a couple of years ago.
As always, if there are any comments and/or questions, feel free to get a hold of me!
Seth Juarez
Email: sethj@devexpress.com
Twitter: @SethJuarez
Download & Try
Download a free copy of the DevExpress WPF controls that help you build rich and powerful user interfaces with the versatile MVVM framework.