How to: Put WKL controls into forms by code
Create forms with WKL controls from a build script instead of inserting the controls by hand, for example in an application whose forms are generated or kept as text in source control.
Requires WKL Forms Object Library 1.31 or later.
Solution overview
- Not with CreateControl.
CreateControlwithacCustomControlcreates the control's frame but no ActiveX object: Access needs the control's saved data (OleData), which only Access writes when it saves a form that contains the control. - With a control block. A control block is the
Begin CustomControl … Endsection of a form saved withSaveAsText. The build script inserts it into the text of its form and loads the form withLoadFromText; Access creates the control from the block'sOleData. - Settings in Design view. After loading, the script opens the form in Design view and sets the control's properties through
.Object(for aWklValidator, itsRules); Access saves them with the form.
Every WKL control comes with a released block in its default state (inserted through Access's own
dialog box, the way a developer inserts it, and saved by Access for the release). The blocks are in
the control-blocks folder of the release package (docs/control-blocks in the repository), one
file per control: TreeView, TreeList, Gantt, Grid, Splitter, DockLayout, StatusLabel, NavBar,
Button, Validator, ToggleSwitch, TokenBox, Badge, PropertyGrid, ButtonEdit, SpinEdit,
Gauge, KpiCard, ActionBar, Drawer, Barcode, Image (<Name>.control.txt).
Each block sits at the top left of its section and has a usable default size. For every release,
each block is checked by loading it into a new form and opening that form in Form view. The build
tool replaces placeholder rectangles with these blocks
(How to: Build an Access application from its text sources).
Implementation
- Create the form as usual (
CreateForm, andCreateControlfor Access's built-in controls), close it withacSaveYes, and export it as text:Application.SaveAsText acForm, "frmIdentity", "frmIdentity.form.txt". The file is UTF-16 (Unicode), the encoding Access uses. - Open the text and find the detail section: the last
Begin Sectionwith its name, for exampleName ="Detail"(the name depends on the language of Access). Its controls are inside aBegin … Endblock within the section. Insert the block's lines before that innerEnd, indented like the other controls. A section without controls has no innerBegin … End: insertBegin, the block, andEndbefore the section's ownEnd. - Change the block's
Name ="Validator1"to the control's name in the form, and addLeft =…andTop =…lines (in twips) for its position; the block doesn't contain them, because Access omits values of 0.WidthandHeightare already in the block. - Write the text back as UTF-16, delete the form (
DoCmd.DeleteObject acForm, "frmIdentity"), and load it:Application.LoadFromText acForm, "frmIdentity", "frmIdentity.form.txt". - Set the properties in design view:
DoCmd.OpenForm "frmIdentity", acDesign
Forms!frmIdentity.HasModule = True ' the validator needs a module; an empty one is enough
Forms!frmIdentity!Validator1.Object.Rules = "{""fields"":[{""field"":""Login"",""required"":true}]}"
DoCmd.Close acForm, "frmIdentity", acSaveYes
Remarks
- One block per control type. A block contains the control's class (
Class ="WklForms.…") and its saved properties in their default state. Use the blocks from the release you're working with; a block from an older release still loads into a newer one (any settings it lacks take their defaults). - Names. No two controls on a form can have the same name; change
Namebefore loading.
Related topics
- API reference: WklValidator