Populate combobox in Powerdesigner form

There are two ways for populating comboboxes in Powerdesigner forms. The first one uses templates and is the prefered method but it lacks flexibility. The second one is a bit of a hack and involves runtime search/replace in the form definition XML.

Using extended attributes with templates

You start by creating a template that runs GTL code for tetching the items that you want to populate the combobox with. In this case we select Entities with stereotype 'Staging View' and make sure the result is sorted.

.foreach_item(Entities,,,%Stereotype% == "Staging View",%Item1.Code% >= %Item2.Code%)

Then you create an extended attribute that uses the template in the list of values field.

And when you add the extended attribute to a form, the list will be populated with the result of the template.

Call the form with the folowing code:

Sub %Method%(obj)
    Dim dlg
    Dim Model

    Set Model = obj.Parent
    Set dlg = Model.CreateCustomDialog("%CurrentTargetCode%.Select Table")
    If not dlg is Nothing Then
        If dlg.ShowDialog() then
            MsgBox dlg.GetValue("cmb_StagingViews")
            MsgBox "Cancel clicked"
        End if  
   End If
End Sub

Using replace in XML form definitions

The problem with the template method is that you cannot parameterize the template. If you need data from a different object than the current object, you're out of luck. If you still want to populate a combobox you have to use a 'hack'.

For this method you create a form like you always do but you put placeholders for the value and the list of values.

Each form has an XML definition. It can be found on the XML tab of the form creator.

The XML for this form looks like this:

<Form  >
   <ComboBox Name="cmb_SelectSource" Caption="Select source" Value="cmb_SelectSource.Value" Values="cmb_SelectSource.Values" ExclusiveList="No" SizeInChars="50" HorizontalResize="Yes" ReadOnly="No" />

The trick with this method is that you can change the XML at runtime. It works like this:

         Set FrmDef = dlg.FormDefinition
         ' Save the form definition so we can restore it later
         XML = FrmDef.Value
         ' Replace the placeholders with actual values
         FrmDef.Value = Replace(FrmDef.Value, "cmb_SelectSource.Values", Sources)
         FrmDef.Value = Replace(FrmDef.Value, "cmb_SelectSource.Value", "")         
         If dlg.ShowDialog() then
            ' restore the form definition
            FrmDef.Value = XML

Click here for a full code example

Make sure that you restore the form definition when the user closes the form either by Ok or Cancel. The form definition will be changed in the extension and if the user saves the extension with the replaced value, your code won't work anymore.