By: Oleg Zhukov
Abstract: This article explains how to use both basic and advanced features of Developer Express UI controls in ECO WinForms applications
ECO is an excellent framework for designing and supporting business objects. However, unlike its predecessor Bold it doesn’t provide any specific components to build user interface layer. Instead it supports .NET databinding architecture that allows developers to use ECO with any third-party .NET controls they like.
Nevertheless in practice many developers face difficulties using various powerful UI libraries in ECO applications. One of the most popular .NET user interface component packs is Developer Express XtraLibrary (DXperience). It consists of many feature-rich controls including powerful grids and editors. In this article I would like to explain in detail how to use both basic and advanced features of Developer Express UI controls in ECO WinForms applications.
Let us start with creating the model. Go to File -> New -> Other -> ECO WinForms Application to create a new project. Once the project is created proceed to editing Package_1 model. (I will assume the reader is familiar with ECO basics so here I present the final model without intermediate steps.)
For testing purposes let us create some test data inside WinForm constructor. Note that every ECO class in our model is equipped with parameterized constructor to set each object’s properties during its creation.
m_EcoSpace = new Using_ECO_with_DXEcoSpace();
rhRoot.EcoSpace = m_EcoSpace;
m_EcoSpace.Active = true;
private void createTestData()
Customer john = new Customer("John", EcoSpace);
Customer pete = new Customer("Pete", EcoSpace);
ProductDescription milk = new ProductDescription("Milk", 1, EcoSpace);
ProductDescription honey = new ProductDescription("Honey", 1, EcoSpace);
pete.orders.Add(new Order(new DateTime(2006, 11, 1), EcoSpace));
pete.orders.Add(new Order(new DateTime(2006, 11, 5), EcoSpace));
pete.orders.lines.Add(new OrderLine(milk, 10, EcoSpace));
pete.orders.lines.Add(new OrderLine(honey, 2, EcoSpace));
pete.orders.lines.Add(new OrderLine(milk, 1, EcoSpace));
pete.orders.lines.Add(new OrderLine(honey, 15, EcoSpace));
Now we are ready to place controls on the form. Our first task will be to select a customer from a lookup combo box and see the list of his orders.
Select DevExpress LookUpEdit from a tool palette.
Put it on the form and give it a name “customerLookUp”. It must be bound to a data source containing a list of possible customers. For that create an Eco expression handle “ehCustomers” and set the following properties in object inspector
ehCustomers.RootHandle = rhRoot
ehCustomers.Expression = "Customer.allInstances"
customerLookUp.Properties.DataSource = ehCustomers
customerLookUp.Properties.DisplayMember = "name"
customerLookUp.Properties.ValueMember = "self"
Here we use “self” data source column to refer to the actual customer (not his name). In order to create this column edit ehCustomers.Columns collection. Just add there a “self” column with “self” as its expression.
Add a new reference handle rhCurrentCustomer. As you see from its name it will reference the customer currently selected in the lookup box. Don’t forget to set its properties:
rhCurrentCustomer.EcoSpaceType = Using_ECO_with_DX.Using_ECO_with_DXEcoSpace
rhCurrentCustomer.StaticValueTypeName = "Customer"
And add the following line to the bottom of the WinForm constructor:
rhCurrentCustomer.EcoSpace = m_EcoSpace;
Unfortunately DevExpress LookUpEdit doesn’t support currency manager architecture. That is why you should handle its EditValueChanged event to reflect the selection change:
private void customerLookUp_EditValueChanged(object sender, System.EventArgs e)
Now if you run your application and try to select a customer from the lookup edit you will see unwanted “self” column in the dropdown list.
That is because by default the lookup edit displays all columns from its data source including “self” column. To eliminate it edit customerLookUp.Properties.Columns collection. First click “Populate Columns” and then remove one that points to “self” handle column.
Now let us display orders list for the selected customer. First place an expression handle and a DevExpress GridControl on the form. Name them “ehOrders” and “gcOrders” respectively. Then change their properties as follows:
ehOrders.RootHandle = rhCurrentCustomer
ehOrders.Expression = "self.orders"
gcOrders.DataSource = ehOrders
And again you should remove unneeded column from orders grid. Right click grid control and select “Run Designer”. Then select “Columns” tab and remove “colCustomer” from the list. Or simply click on the column header to select it and press “Delete”.
Now we will make each order row expandable to show related order lines. For this purpose we add a nested column to ehOrders.
Open ehOrders.Columns collection. Add a new column named “lines” with “self.lines” expression. Set “Nested = true” for this column.
Nested column is a handle column whose value is a list of objects rather than a single object. Nested columns can be added automatically if you set “AddDefaultNestings = true” on the handle.
Run the application. If everything is correct you will see this:
Here we see that three columns are created automatically in the inner grid. One may wonder if it is possible to adjust these columns. Yes, indeed, it is possible at two levels.
First is the data source level. We may edit OCL columns for the “lines” nesting just like for any Eco handle. To do this open ehOrders.Nestings collection and add a new nesting named “lines”. And set the other properties as shown.
Next, edit the Columns collection for just created nesting. Add two columns “quantity” and “product” with expressions “self.quantity” and “self.product” respectively.
Finally link “lines” nested column (from ehOrders.Columns collection) with this nesting by setting its NestingName = “lines”.
Run the application again. It should look like this:
The only thing left is to be able to view and change the product associated with particular order line.
Another way to adjust inner grid columns is to edit detail view columns. According to DevExpress terminology the grid with master rows (orders in our case) is referred to as the master view. Detail grids within main view are called detail views. It is important to realize that there may be many detail views (as much as the number of rows in the master view). And if we want to apply some settings to the detail columns we should make changes to each of the detail view. Fortunately it is possible to create and set up a pattern view so that all detail views inherit settings from this pattern view.
Now we will create a pattern detail view and adjust a “product” column for this view.
Run grid designer via grid control’s context menu. Select “Views” tab and click “Click here to create a new level”. Then for the created level click “Click here to change view” and select “GridView”. Next, click on the newly created level “Level1” and change its name to “lines”. This is how we link the created pattern view to the “lines” nested handle column.
By now the levels layout should look like this:
For the grid to look less laden set “gridView1.OptionsDetail.ShowDetailTabs = false” and “gridView2.OptionsView.ShowGroupPanel = false”.
Open the grid designer again (if closed) and select gridView2 (it’s our pattern detail view). Then open “Columns” tab and add two columns. Name them “colQuantity” and “colProduct”. And assign the following properties:
colQuantity.Caption = "Quantity"
colQuantity.FieldName = "quantity"
colProduct.Caption = "Product"
colProduct.FieldName = "product"
If you run the application you will see that there are almost no changes. But this is not quite correct since now we have full control over the “Product” column, and it brings us just one step away from using an embedded lookup editor for this column.
Edit “colProduct.ColumnEdit” property (either in object inspector or in grid designer dialog). Open dropdown list and select “New->LookUpEdit”. A “repositoryItemLookUpEdit1” will be created. First change its name to “productLookUpEdit”. Before modifying other properties we need an expression handle listing possible product descriptions. So place a new expression handle named “ehProductDescriptions” on the form. Add a “self” column with “self” expression pointing(?) to the “ehProductDescriptions.Columns” collection. Here are the other property values you should set:
ehCustomers.RootHandle = this.rhRoot
ehCustomers.Expression = "Customer.allInstances"
productLookUpEdit.DataSource = ehProductDescriptions
productLookUpEdit.DisplayMember = "name"
productLookUpEdit.ValueMember = "self"
And the last thing to do is to remove useless columns from the product lookup editor. It’s done by modifying “productLookUpEdit.Columns” collection. We have already done similar work for the customers lookup box before.
Finally, this is how the resulting application looks:
We have demonstrated how to bind together ECO and popular DevExpress UI library. But in fact it is only a particular case of more general idea that ECO is a very extensible framework. Any database engine, any presentation layer (Web/Windows), custom ocl expressions, custom cache implementations and more… And if the question is “Can I use it with ECO?” the most probable answer is “Yes, certainly!”
The full source code of the example can be downloaded from CodeGear CodeCentral portal. Here is the link to it: http://cc.codegear.com/Item/24523. Also visit the author’s website.
Download Delphi XE8 now!
Webinars on demand!
More social media choices:
Delphi on Google+
@RADTools on Twitter
Server Response from: ETNASC02