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 StrataFrame Controls

Subclassing Strataframe controls saves time, and also lets you have it your way

Les Pinter

Coding time: 10 minutes.

Jump to:   Project Setup   Add a Subclassed Control   Add Behaviors   Add Custom Properties   Conclusion 



This may surprise you, but the WinForms controls that Visual Studio provides should never be placed on a form.

The reason is that you probably have some preference as to how you want labels, textboxes, lists and so forth to look. If the gal paying the bill tells you to change them because they don't look pretty, as once happened to me on a big government project, if you used the WinForms controls, you're up all night changing every font on every control on every screen. And then your client will change their mind again.

There's a better way, and subclassing the controls is that way. Instead of putting WinForms controls on your forms, you put your subclassed controls on the forms. Change the font in your subclassed control, and it ripples through all of the screens.

This works as well with StrataFrame form controls as it does with WinForms controls, and for the exact same reason. It lets you make cosmetic, and even behavioral, changes, in just one place. It's the right thing to do.

In this article you'll learn how easy it is, and become a convert.

Setting up your project

In Visual Studio, select New, Project, and from the StrataFrame menu pick New WinForms Project. I'm using Visual Basic, but the code in this article will appear in both C# and VB. Your IDE will look like Fig. 1:

I know I'm going to need a Business Object to bind my textbox and other controls to, so let's add it right now. Rightclick on the project and select SF Business Object, giving it the name CustomersBO. Rebuild the project, Now, from the StrataFrame menu pad select Business Object Mapper, Click New, and name the new project SubClassedControls (Fig. 2). Configure it to use the StrataFrameSample database and save the connection string (Fig. 3); finally, configure the CustomersBO object to be based on the Customers table in the StrataFrameSample database (Fig 4); the BO will be created with properties corresponding to the columns in the table (Fig. 5).

Finally, double-click on CustomersBO, switch to code view, and add the following code in the Data Retrieval Methods region:

C#: public void fill() { this.FillDataTable("SELECT * FROM CUSTOMERS"); }

VB: Public Sub fill()
      Me.FillDataTable("SELECT * FROM CUSTOMERS")
    End Sub

Subclassing the StrataFrame Controls

Right-click on the project and select Add, Class (it's down at the bottom of the context menu). Name it SubClassedControls. Replace the entire contents of the file (which is only two lines) with the contents of Listing 1:

It might look a little odd that the class name and the file name aren't the same, but it's absolutely not required. In fact, we can add more classes to this same file. For example, let's add a StrataFrame Label control, setting the font to Tahoma and the color to Navy blue (Listing 2):

and rebuild the project.

Now, add a SF Maintenance Form named frmCustomers to the project (Fig. 6):

Double-click on frmCustomers to open your new form, then press Ctrl+Alt+X to display the toolbox, and you'll see that both the CustomersBO business object and both of your new textbox controls are in the current project toolbox tab. (Fig. 7)

(Note: If you don't see what's shown in Fig. 7, click on Tools, Options, scroll down to the next-to-the last category (Windows Form Designer) and make sure AutoToolboxPopulate is set to true.)

In Fig. 8 I've added the CustomersBO as well as two labels and three textboxes. Notice that the Property Editor for binding MyTextBox1's Text property to the LastName column of the current Customer record works exactly as would a normal StrataFrame textbox.

frmCustomers needs to fill the business object in it's load event; here's the code (Listing 3):

Listing 4 shows the code to handle the little menu that I added to Form1:

And it works! (Fig. 9)

Adding Behaviors

You can also modify the way your control works; in fact, that's the main reason developers subclass controls - although controlling their appearance is nothing to sneeze at. Say, for example, that you want the textbox that has the focus to have white letters on a blue background; how hard would that be?

Add the code in Listing 5 to your MyTextBox class:

Run the form again, and notice how easy it is to spot which textbox the cursor is in (Fig. 10)

Adding a Custom Property

You may want to add a behavior that depends on the setting of a property. Both the property and the method that uses it need to be added to the subclassed control. For example, let's add a Required property, and code that displays "REQUIRED!" in a textbox if its Required property is set to True and the user leaves it empty.

(NOTE: StrataFrame actually already has such a rule, and it's built into the Business Object; but a simple example is needed here, and I can't think of anything useful that SF doesn't already do.)

Public properties are like fields, except for two important differences:

  1. They appear in the Property Sheet and can be set visually by the developer; and
  2. You can include code to react to the getter or setter at the moment that the property is assigned a value or when the value is read, respectively. We won't do either in this example; in this case, we'll actually test for a value of True in the Leave event of the textbox.

Attributes for custom properties

The Required custom property will need several attributes:

  • Bindable() - Permits binding to an object's Text (or other) property
  • Browsable() - Makes the property visible in the Properties Sheet
  • Category() - used to name a category in which your property will appear

If you leave them out, you won't be able to see the attributes in the class browser. And several of these attributes won't appear in the IntelliSense list of available attributes unless you've included using/Imports System.ComponentModel at the top of the file, so do that before you try to type the attributes.

The property will need a private field in which to store the property, so you'll be adding that, too.

To add the property, just type the code in Listing 6:

Code to use the property

To use this property, just add one line of code at the end of the Leave event in the MyTextBox class:

C#: If (Required & Text == "" ) { Text = "REQUIRED!"; }
VB: If (Required And Text = "") Then Text = "REQUIRED!"

Set one of the textboxes' new Required property to True (Fig. 11) and run the program, leaving all of the textboxes blank. (Fig. 12)

Custom properties can give you an additional level of control to let you set behaviors in the Properties Sheet at design time. They're a valuable addition to your arsenal.


Subclassing your controls should be just about the first step in a new project; it gives you a mechanism for decorating your controls to suit your users without stopping the show every time they want a new color for their labels. You can subclass the StrataFrame controls just as easily, thereby retaining all of their useful properties and behaviors and adding your own, as well as giving you this quick and easy ability to standardize appearance and behavior. I hope you'll start every project with this simple step.

See 'ya.


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