Creating a Property Grid for a User-defined Component

Description

One way to create a Property Grid for a User-defined Component is to use the Property Grid builder in Action Scripting to generate the markup. This is invoked by creating a New Script (using Action Scripting), adding a new action, and selecting Xdialog Windows|Display an Xdialog Box.

Discussion

In the Xdialog builder, assign a variable name, use a style of Property-grid style Dialog, and press Define Property-Grid Dialog. Add Categories and Items to define the grid you want, then view the resulting code and extract the markup. This builder is documented in the article Property-Grid Style Dialog. Additional field types are documented in the article Property Grids.

A faster way to create a Property Grid, at least once you know the syntax, is to edit the markup directly. The Property Grid comprehensive sample will show you all the essential elements if you're not already familiar with them. Copy that code to a new script using Xbasic and run it to see how it works and read the help in context; compare that to the code to understand what you need to do to get the desired effect.

Properties and property grid for the Demo component 

If you open componentBuilderPropertyGridDefinition.txt in your programming editor you will discover that the sample property grid, mirabile dictu, is for a light-weight grid. All we need to do is uncomment it and wire up the functions it needs.

After you uncomment the property grid, the file should look like this:

^^Light Weight Grid Properties
  state=opened

  ++Data source type
    var=wp.dataSourceType
    help=Specify if the Grid gets its data from a SQL database, or .dbf tables.
    type=combo
    data=SQL,DBF
    event=setDirty
    
  ++Table or View
    var=wp.dbfType
    help=Specify if the Grid gets its data from a single table of a view that joins multiple .dbf tables
    show=wp.dataSourceType="dbf"
    type=combo
    data=@choices.dbfTableOrView
    event=setDirty
    
  ++Table name
    var=wp.dbfTableName
    type=smart
    data=wp.dbfTablename=bf.tablePicker(wp.dbfTablename)
    show=wp.dataSourceType="dbf" .and. wp.dbfType = "Table"
    help=Specify the table name.
    event=setDirty

Save the file and try to create a new Demo component. Try the property tab. You'll see the three light-weight grid properties. The Data source type combo box will work correctly, as the choices were defined inline. The other combo box and the smart field will not work properly.

Fixing the second combo box is easy: edit componentBuilderChoiceListsForPropertyGrid.txt, uncomment the sample, and save the file. When you're done it should look like this:

dim choices.dbfTableOrView as c = comma_to_crlf("Table,View")

Try to create a new Demo component, and now both combo boxes should work.

Now for the smart field. Start by editing componentProperties.txt, and once again uncomment the code. The file should then look like this:

dim wp.dataSourceType as c = default "DBF"
dim wp.dbfType as c = default "Table"
dim wp.dbfTableName as c = default ""
dim wp.sqlConnectionString as c = default ""
dim wp.sqlQuery as c  = default ""

Now go back to builderFunctionDefinitions.txt. We'll have to fill in the bodies of the two functions at the end of the file. The code you need is:

function getDataSourceType as c (type as c )
 
  getDataSourceType = ui_get_text("","", wp.dataSourceType)
  if getDataSourceType = "" then 
    getDataSourceType = type 
  end if 
end function
 
function tablePicker as c (tablename as c )
  tablePicker = a5wcb_tablePicker(tablename)
end function

There's one more thing we need to do: make the component actually use the table we select. In builderFunctionDefinitions.txt, find the line

t = table.open("Builder Type")

and change it to

t = table.open(e.tmpl.dbfTableName)

Now a new Demo component should be able to select and display a DBF table.

Supporting SQL connections and DBF expressions are left as exercises for the student.

What if I have good defaults? 

If you create a new Demo component and try to preview it immediately, you'll get an error message that you have not specified any properties, and quite rightly so. But suppose you have good defaults, so that your component can run "right out of the box?"

In that case, set

wp.flagOKToPreviewBeforeUserEdits = .T.

in componentProperties.txt. Now you can create a new component and immediately preview it.

See Also