Creating a Property Grid for a User-defined Component
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.
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.
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 firstname.lastname@example.orgTableOrView 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.
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.