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

Modeless Data Entry Forms

If you don't like requiring users to 'Click to edit', this is for you

Les Pinter

Coding time: 15 minutes.

 Jump to:   Setting up the project   Adding the Business Objects   Data Retrieval Methods   Building the Modeless Form   Navigation   Conclusion 



In the realm of add/edit/delete forms, there are two kinds of developers:

  1. Those that like for their users to click an "Edit" button before they can change data, then either "Save" or "Cancel" (or "Undo") to end the editing state. Controls are initially disabled, and must be enabled by choosing either the "Edit" or the "New" (or "Add") button.; and
  2. Those that hate the kind of screens described in (1), above, preferring what they call "modeless" editing, where the user is always in edit mode.

<rant>These people don't even go to the same parties. The latter consider the former unsophisticated and lacking in talent; the former consider the latter to be effete snobs looking for a way to raise themselves above the hoi polloi. I'm reminded of the war between VB and C# programmers, who occupy the same relative positions in their language battles. They're both wrong. It's just two ways of doing things.</rant>

Anyway, if you need to do the "modeless" type of form, StrataFrame has all sorts of features built in to make it easier. That's the subject of this article. And just to add a little pizazz, we'll build a custom toolstrip using some other cool StrataFrame controls.

But first, you'll need to set up the project. If you're familiar with setting up a StrataFrame project, adding business objects, and writing data retrieveal methods, you can skip the next 3 sections and jump straight to building the modeless form,

Setting up the project

As always, we start with a StrataFrame Windows Application project. You'll have to choose the language, but in this article we'll include the code for both C# and VB. The starting project appears below:

I'll first add a StrataFrame MainForm:

You'll need to change the initially displayed form from Form1 to your new MainForm. StrataFrame uses the InitApplication method of startup program called AppMain in VB and program.cs in C#, which tells the application which is the starting form in the InitApplication method. In program.cs, it's around line 139:

    private static void InitApplication(InitializingApplicationEventArgs e)
      { e.Forms.Add(typeof(ParentChildForms.Form1)); }

In AppMain.vb it's near line 119:

    Private Shared Sub InitApplication(ByVal e As InitializingApplicationEventArgs)

By default, it's set to Form1. Change it to the form you want to see when the app starts - MainForm if you're using a MainForm with a menu, or frmGrids if you just want to see the Grids form. In Fig. 3 I've changed the C# version:

Note: In VB, the project Properties sheet lets you set the startup object; don't do it, because it will bypass the Main routine in Program.vb that initializes the StrataFrame framework.

Now, just to familiarize yourself with another neat StrataFrame feature, drag and drop a ThemeManager from the StrataFrame toolbox onto the form, select it, open the Properties Sheet, and pick "CoolWave" from the list of available Themes. You'll see the results in the forms we're going to do today.

Adding the business objects

StrataFrame uses Business Objects (table classes) that it generates directly from your datasource. We'll use the Customers table from the StrataFrameSample database that installs with StrataFrame. Right-click on your project and select Add, New Item, then pick SF Business Object from the available items. Be sure to change the name to CustomersBO before you click Add (Fig. 5)

You've added an empty class; we'll configure it shortly.

Now, from the StrataFrame menu pad in the IDE menu, select Business Object Mapper. Since the project isn't yet pointed at a data source, the little red "x" over the Project name and the business objects below it indicate that they're not yet configured. Not a problem: Select the project name from the Available Projects tree and click on the Configure Project link, which becomes enabled when you select the project name (Fig. 6).

In the Choose Project dialog that appears, click the New Button. Then, from the Project Properties screen that appears (Fig. 7), fill in a project name and description. Leave the Database Deployment Toolkit radiobutton selection in the Default Structure Settings group as it is; this is an external file used in the IDE where StrataFrame stores project information. You can also store it in a database, but we generally won't do so. Be sure to select the new project (on the Choose Project dialog page) after you create it.

You should, however, build and store your SQL connection string information by selecting the little button with the three dots just to the right of the SQL Server Connection string textbox in the Default Connection Strings group (circled in Fig. 7, above) to bring up the Database Connection Wizard (Fig. 8)

Once you've configured the project, highlight CustomersBO and click on the Configure Business Object link to produce the screen seen in Fig. 9:

Now select the SQL Server radio button and click the Select Source button: You'll be able to select the StrataFrameSample database and pick the Customers table (Fig. 10).

When you return from selecting tables and fields for the two business objects, you'll see that the little red "x"s have disappeared. You can double-click on any row in the Business Object Mapper to select other options for each field (for example, to replace a NULL value in a column with a blank or zero) (Fig, 11). However, for the moment we don't need to do anything else.

Select Rebuild All, and close the BOM dialog.

Data Retrieval Methods

You might think that a Business Object knows how to return data; it doesn't. You have to add one line of code in each one. DoubleClick on the CustomersBO and select Click here to switch to code view. Expand the Data Retrieval Methods region and type this in:

Rebuild the project, and you're ready to build a modeless editing form.

Building the modeless form

The form design that I came up with is shown in Fig. 12:

To create it, add a StrataFrame Standard Form to the project, making it the startup form in program.cs (or program.vb) as shown in Setting up the Project, above. Add a DefaultApplicationTheme, setting its Theme property to BlueSkies. Next, add a GradientFormHeader (which sports Title and Details properties that provide the major and minor headings for the page), a ThemedLinkMenu and a ThemedPanel. Drop a couple of ThemedGroupBoxes on the ThemedPanel and change their captions to "Customer Name" and "Address, City, Country".

You'll need a CustomersBO to bind the TextBoxes to, so drag the CustomersBO created in the Creating Business Objects section onto the form. Then, add three labels and three textboxes from the StrataFrame toolbox to each of the ThemedGroupBoxes. Verify that the BusinessObject of each TextBox is CustomersBO, and then set the BindingField property of each textbox to the appropriate field, and set the Text property of each label to the strings shown in Fig. 11.

Now, here's the key: Change the CustomerBO's ManageUiReadOnlyState property to False. StrataFrame business objects have this property precisely so that you can decide whether to initially display your controls enabled or disabled. It defaults to True, but it has to default to something. So if you're one of those people who prefers modeless forms, don't feel offended that your Weltanshauung wasn't the default.

<rant>Okay, go ahead and feel offended; but don't forget to change the property.</rant>

We still didn't go get any data, but that's easy: Double-click anywhere on the form that's not a control to bring up the form's Load event, and type in one line of code:

VB: CustomersBO1.Fill()
C#: CustomersBO1.fill();

At this point you can press F5 to run the application and see the data from the first record in the Customers table on the form. So far, so good.


Select the ThemedLinkMenu and click on the button with the three little dots to the right of the ItemCollection property in the StrataFrame: General Settings tab. You'll see a MenuItem Collection Editor like the one shown in Fig. 13, below, except that it won't yet have the nine items that I've typed in. So type them in, adding the Key and Title strings as shown in Fig. 13.

These MenuItems don't have individual event handlers; rather, you write a single event handler for the ThemedMenu control, then test for the Key of the clicked MenuItem, as shown in the code listing below. Note that the Title property is what is displayed, not the key. They're usually the same, but if you don't fill in the Titles, you won't see anything, and like Paul Simon, you'll wonder what went wrong.

The code is deceptively simple; The CustomersBO business object already contains a Navigate method, as well as Add, DeleteCurrentRow, Save and Undo methods.

This is what first got me hooked on StrataFrame. SF's Business Objects are like Type Datasets on steroids. Actually, they're typed datasets done right. In standard .NET, you have to associate a BindingSource with your datatable, then use the BindingSource's methods to MoveNext, MoveFirst, RemoveAt, AddNew, and whatever. Why? It's very confusing; StrataFrame does it right.

<rant>Maybe Microsoft will buy Trent's code and save themselves a boatload of time and effort. Memo to Trent: If they offer $35,000, ask for more.</rant>

Note that for this to work, you need to name the ThemedLinkMenu lmControlMenu, and add the following three Imports (usings in C#) to the top of your file:

Imports MicroFour.StrataFrame.UI.Windows.Forms
Imports MicroFour.StrataFrame.Messaging
Imports MicroFour.StrataFrame.Business

Anyway, press F5 and see if navigation works. Pretty cool, ┬┐no? (Sorry, force of habit; I grew up in Mexico...) I didn't add in the little graphic images, but obviously they add to the sex appeal of the UI. Do whatever's consistent with your personal value system, as we used to say in the Sixties. Boy, the stories I could tell...

<rant>In several of the listings shown below, you'll find a property called IsDirty. Once a few decades ago, some 23-year-old Microsoft programmer high on Coca-Cola and sleep deprivation thought that it would be cute to refer to a record that had been changed by the user as "dirty". I'll bet they giggle for hours over that one. Anyway, we're stuck with it. I loathe it, but nobody cares. Anyway, if you see it, it means DataHasChanged.</rant>

There are a couple of other chores that are necessary. Clearly, we don't want users clicking on "Next" when they're already at the last record; they just wonder why it isn't working! So add these two routines:

The only thing missing is to call both routines when the form loads, to initialize the navigation controls; so modify the form's Load event handler as follows:


and add two more handled events:

These two little event handlers take advantage of the IsDirtyChanged and Navigated events in the CustomersBO business object. That's the genius of StrataFrame. Whatever you need, it's probably in there; you just have to find it and hook into it.


The application described in this article just takes a few minutes to code, but it will give you a pretty good idea of the flexibility of the StrataFrame framework. You don't have to do things in a certain way. Properties, events and methods exist to permit a wide range of user interface approaches to common data handling problems.

In the next article, we'll look at how easily parent-child forms can be constructed and wired up.


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