CODE Pathway Gateway
   Almost free!  One day of FREE VFP to WPF evaluation of your FoxPro app ONSITE
   Free!  Read the foreword to Les' new book (available here)...
Skip Navigation Links

Subclassing Business Objects

Subclass Strataframe business objects to add custom properties

Les Pinter

Coding time: 20 minutes.

Jump to:   Add a Business Object   Add a Property   Subclass the BO to add a property   Conclusion 



Business objects are the mechanism that makes data access simple in StrataFrame applications. A single function call retrieves your data into the business object; a single "Save" method saves changes. Couldn't be simpler.

Sometimes we need to do something with data from tables before it's useful. The canonical example is age, which usually isn't stored in a table; rather, it's derived using the date of birth. Age is called a custom property, and although it's not stored in the table, it would be nice if we could refer to it in code as if it were a column in the table. That's what custom properties are for.

Custom properties can also be useful if you intend to do reporting from a table, and want to add some calculated fields to the business object. If they're only used for reports, why burden the primary business object with them? It's better to subclass the business object, then add the custom properties to the subclass.

In this example, we're going to use the Customers table from the StrataFrame Sample database, and add two variations on the customer name: A "Last name first" property in the form "LastName, comma, space, FirstName", and another in the form FirstName, space, LastName. And to make it interesting, we'll create the LastNameFirstName property in the primary business object (called CustomersBO), then subclass CustomersBO as CustsBO and add the custom property FirstAndLast to CustsBO.

Adding a Business Object

I've created a project of type StrataFrame Windows Application, which contains a single form called Form1. I'll use that as my menu for launching two forms that will use the two business objects that I'll create based on the Customers Table from the StrataFrameSample database.

In Fig. 1, I selected the Business Object Mapper from the StrataFrame menu pad. It shows a red "x" beside the project name, because it hasn't yet been "configured" - i.e., it doesn't know where the data is coming from. We can take care of that right now.

Click on the Configure Project hyperlink under Actions. Fig. 2 will appear.

I typed in a project name and description, then clicked on the button with the three little dots on it after the SQL Server Connection String textbox. We'll build this now so that the application can use it later on. The project information is stored in the DDT, a local cache on your computer. (It could also be stored in SQL Server or any of several other caches.)

The first time you run any StrataFrame project, it looks for stored database connection information. If it doesn't find any, it knows that it's being run for the first time and asks the user to identify the server and database to use. The dialog that walks the user through this is called the Database Connection Wizard. Press F5 to bring up Fig. 4, select your server and the StrataFrameSample database, and click Next:

The confirmation screen shows the SQL Server Connection that will be used on your workstation.

This connection string (shown in Fig. 6, below) will be read each time you run the application. If you want to get rid of it and start over, you can erase the two files found in your Users\%yourname%\MicroFour folder.

When you finish, the red "x" beside the project name will be gone. However, you still don't have any business objects, which would ordinarily appear below the project name. No worries; we'll just add one.

Select the project in the Solution Explorer and select Add, New item (Fig 8);

Select an SF Business Object, giving it the name CustomersBO (Fig. 9):

The business object will appear in the Solution Explorer (Fig. 10). It still doesn't have any column definitions or custom code; we can add that later.

Fig. 11 shows the empty Data Retrieval Methods where we can add as many SELECT statements as we need. They're defined as public void methods (Public Subs in VB ) because they don't actually return anything; they fill the business object with data. Early on, StrataFrame included a default Fill method that returned all records; but it seemed to give users the impression that they always needed to return all records. So it was eliminated. We're about to write one that returns all records, but consider yourself forewarned.

Type this:

    public void fill() {}
and press Enter,

Then go between the little squiggly braces and begin to type Fill.... IntelliSense will helpfully show you several methods built into your new Business Object that might be what you're looking for; FillDataTable() is just what we wanted, so press the Tab key to complete it (Fig. 13):

FillDataTable takes a single parameter - a SQL Statement; "SELECT * FROM CUSTOMERS" will do the trick. Note that you can provide a WHERE clause, or you can create a SQLCommand and then define and add a Parameter. There are a number of examples in the StrataFrame documentation, and we'll provide more in subsequent articles. But the SQLCommand is a .NET artefact, not a StrataFrame object. For this example, a simple SELECT will do fine.

Now if you return to the IDE and select Business Object Mapper from the StrataFrame menu pad (Fig. 15)...

you'll see that the CustomersBO object appears below the project name, with a little red "x" beside it to indicate that it hasn't yet been configured. Highlight CustomersBO and click on the Configure Business Object hyperlink:

Select the SQL Server RadioButton and click Select Source (Fig. 17):

Pick the StrataFrameSample database, then the Customers table from the treeview (Fig. 18):

The Business Object Mapper will show the columns in the table, which are now exposed to your application as properties of the business object (e.g. CustomersBO.cust_FirstName).

Click the Rebuild All menu button to generate the Business Object code (Fig. 20).

Adding a Custom Property

At this point, if you create a CustomersBO object in a form (by dropping one on the form from the ToolBox, which will create an object named CustomersBO1), you can refer to the contents of the cust_FirstName column in the current record using the notation CustomersBO1.cust_FirstName.

This will be a read-only property, as is usually the case. You have to have actual columns in the database table in order to store the text - although you could create a set method that took what you had typed in using the lastname, comma, firstname format, parse the text, and update the firstname and lastname fields. But it's not the normal case.

DoubleClick on CustomersBO, then click on the Switch to Code View hyperlink. Create a Custom Properties region and type in the code to add a "Last Name, comma, First Name" property (Listing 1:):

A word is in order regarding the GetCustomBindablePropertyDescriptors code in the above listing. StrataFrame uses these to react to properties, so you can't just declare a custom property as you ordinarily would in .NET. This little bit of code is required.

This becomes an issue when you subclass a StrataFrame business object that already has a custom property; you can't duplicate the FieldPropertyDescriptor code; you instead have to get any existing ones (using the GetCustomBindablePropertyDescriptors() call), then add the new one in the current subclassed code. You'll see how this is done in Listing 3.

You'll be missing a couple of using/Imports statements; add these to the top of CustomersBO:

  C#: using MicroFour.StrataFrame.UI.Windows.Forms;
      using System.ComponentModel;

  VB: Imports MicroFour.StrataFrame.UI.Windows.Forms
      Imports System.ComponentModel

Note: If you had not added the using/imports reference to , you'd see little blue squiggles under BusinessFieldDisplayInEditor (Fig. 21). When you see something like this, right-click on it and select Resolve, and you'll see the recommendation to include using MicroFour.StrataFrame.UI.Windows.Forms (Fig. 22); add it to your using statements (Imports statements in VB) (Fig. 23), and the error will go away.

Using your shiny new custom property

Next, add a StrataFrame maintenance form by right-clicking on the project, selecting Add, New Item, and picking SF Maintenance Form from the available templates. Name it frmCustomersBO (Fig. 24).

Open the new form and drag the CustomersBO object from the Toolbox to the tray below the form (or anywhere on the form, for that matter) (Fig. 25).

Add a TextBox from the StrataFrame Controls & Components Toolbox. You'll notice that the BusinessObject property was automatically set to CustomersBO1, the only available SF Business Object (Fig. 26):

... and voilà, there's your new property (Fig. 27). Select it to databind it to the textbox.

There's just one step left in our form: Add one line of code, right after InitializeComponent (Fig. 28):


You could also create a Load event handler for the form and put the code there. The fill() method puts records into the business object, which was declared at the form level by virtue of being a component, so it doesn't matter where you call it; the data that it returns will be in scope anywhere in the form.

Back in Form1, I added code to instantiate and show the form when the appropriate menuitem was selected:

Code to launch frmCustomers
private void usingCustomersBOToolStripMenuItem_Click(object sender, EventArgs e)
 { frmCustomersBO frm1 = new frmCustomersBO();
   frm1.Show(); }

Private Sub usingCustomersBOToolStripMenuItem_Click( _
 ByVal sender As Object, ByVal e As EventArgs) _
 Handles usingCustomersBOToolStripMenuItem.Click
    Dim frm1 As New frmCustomersBO()
End Sub

Press F5, and the form launches. Hello, what's this?

The first time you run a StrataFrame application, it wants to know which SQL Server and which database you want to use. After you've done this, it's stored in a locally-cached (and encrypted) Connection String, safe from prying eyes, but available to the application the next time it runs. Give it a name (Fig. 29), and then provide the server name and the database name (Fig. 30):

Now you can launch the form from your menu (Fig. 31)

The code shown in Fig. 32 launches this form:

The form doesn't do much; I just wanted to demonstrate the fact that the new custom property is indeed bound to the data, and is recalculated as you move from one record to the next (Fig. 33):

Subclassing a Business Object

But what if you want to leave the CustomersBO as simple as possible, and add any additional calculations to a subclass of the object? Reporting is a typical application, and will be discussed in a subsequent article and video. But we can demonstrate the technique today using a trivial example.

No problem. StrataFrame's got you covered. Simply right-click on the project in the Solution Explorer, select Add, New Item, and pick the SF Custom Business Binding Source from the available templates (Fig. 34):

This template creates a subclass of the class that you select in the ensuing dialog, then lets you add other properties to it. The subclass (with a suffix of BO), as well as a Business Binding Source (with a BBS suffix) are created, based on the name you type in; so don't type in Customers; it will just try to create another CustomersBO class.

In Fig. 35 you'll need to check the first two checkboxes, then click Next:

Double-click on the new CustBO object and click on the Click Here to view Custom Code hyperlink. Expand the Protected Methods region and you'll see the generated code shown in Listing 2, below. The items you need to pay special attention to are highlighted in yellow:

You have to make two changes:

  1. Add code to define your custom property, and then
  2. fix the "add custom descriptors" line that's commented out, and uncomment it

Listing 3, below, shows what I did to add a second custom property that displays FirstName, a space, and LastName. The changes are highlighted in yellow:

The generated name conflicts with the original business object CustomersBO, so you have to manually change it to CustsBO. DoubleClick on CustsBO, then click the "Click here to view code" and change CustomersBO to CustsBO (Fig.3 6):

You don't actually have to do this, but due to the way .NET works, if you don't, you'll get two CustomerBO objects in the ToolBox. You can set a preference to be shown the fully-qualified name of toolbox items, and then you'll see that they're not identical; but it's confusing, to say the least, unless you change the name in the code. Just takes a second...

Next we'll add a form to show that the FirstAndLastName property in CustsBO actually works. Right-click on the project and select Add, New Item, and select SF Maintenance Form; give it the name frmCustsBO (Fig. 37):

Drop an instance of the CustsBO object on the form (Fig. 38)

.,..and set the BindingName property to the new property (Fig. 39):

Back in Form1, add a second menu option and the code needed to launch both forms (Listing 4). And you're done.

And both forms work, each using a different custom property, one from the primary business object CustomersBO, the other from CustsBO, a subclass of CustomersBO (Fig. 40):


Next time you're thinking of adding a calculated field to a SQL view, consider using a custom property. Custom properties added to business objects simplify coding, and put computed values in their proper place.

See 'ya


Copyright(C) Pinter Consulting, 2018Tel: +1 (650) 464-6924