Download the AVR 8.0 example
Download the AVR 7.2 example
Download the States DGA archive file
The Windows combo box is very similar to ASP.NET's dropdown box. Both allow users to select a value from a drop-down list. This UI component is very effective in that it presents many choices but uses very little real estate. Typically, these controls show one value and associate that displayed value with a corresponding value. Typically, the value shown is user friendly and the corresponding value represents a less-than-friendly code. For example, you might show the words "Male" and "Female" and associate the codes "M" and "F" with them.
This article shows a way to populate a Windows combo box. The associated downloadable examples, provided in both as 7.x and 8.0, provide an example program that (somewhat boringly!), looks like this:

This program will provides a way to populate a Windows combo box (the same techniques would also work for list box).
The Windows combo box differs from ASP.NET's dropdown box in one important way: The ASP.NET dropdown's Items property is strongly typed to contain ListItems while the Windows combo box's Items property is loosely typed and can contain a list of any objects.
The ASP.NET dropdown box's Items property is very specifically an instance of ListItemCollection (from the System.Web.UI.WebControls namespace). This is a strongly-typed collection of the ListItem class (again, from the System.Web.UI.WebControls namespace). The ListItem class is a very lightweight class and its two most important members are Text and Value. Both are string values and Text is usually used to store what is displayed in the dropdown and Value is used to store what the Text's corresponding value is. For example, in the case of listing US states, a given Text value could be "California" and its value would be "CA." One of the implications of using ListItems to populate the ASP.NET dropdown, is that you cannot directly use numeric values as Value--you'd need to store the string value of the number.
The Windows combox box's Items property, however, is a loosely typed ObjectCollection (a property of the System.Windows.Forms.ComboBox class). This untyped collection can have any object added to it. Thus, unlike ASP.NET's dropdown, you can associate any type of object with a combo box's Items collection. Unlike the ASP.NET dropdown, which requires that you use a collection of ListItems to populate it, the Windows combo doesn't provide a specific class to populate its Items properties. You have to either create one your self or find an existing class that works for you.
To make things easy, and to be able to reuse code, this example shows how to use the Web's ListItem class as the members of a Windows combo box's Items property. At first, this like we're mixing water and oil. To use the ListItem class, we'll need to add a reference to the System.Web assembly--in our Windows app! No matter, we're not really doing anything "Webby" to the Windows app, we just want access to the ListItem class. It offers the two things most uses of the combo box need: something to display and a corresponding value for what's displayed. Yes, using a ListItem constrains that value to a string, but the tradeoff for limiting ourselves to string values is that the classses we need for populating the Windows combo box are already there for us to use--we don't have to write any grungy code to create the classes needed to comprise the Windows combo box's items.
To see this code in action, we'll create a new Windows program. The code works, identically in either AVR 7.x or 8.0 (this article provides downloadable examples for both).
Step 1. Restore the States DGA archive file
If you don't already have it, download (see the link at the top of this page) the States DGA archive zip file and restore it (this is the same file used in the Web class's dropdown exercise). This archive provides the data file this examples uses.
Step 2. Start a new program
Start a new Windows program.
Step 3. Add a reference to System.Web.
Add a reference to the System.Web dll. This is done by right-clicking your project in the Solution Explorer and selecting "Add Reference" from the context menu.

From the "Select a component" dialog, on the .NET tab, scroll down to System.Web and add that as a reference to your project.

The dialogs show in these images are Visual Studio 2005 dialogs, but they look nearly identical in VS 2003.
Step 4. Add a 'using' statement
Add this line at the top of your Windows form class:
Using System.Web.UI.WebControls
Step 5. Create a class to populate a ListItemCollection
Now, things start to get interesting. The code below is a class whose sole purpose is to populate a ListItemCollection with records read from a "States" file (the States file is in a downloadable DataGate archive at the top of this article). The record format for the States file looks like this:
Field name Type Length Decimals Key
-------------------------------------------------------------
State Char 48 0
Abbrev Char 2 0
To keep things clearly separate, use the following class to traverse the States file and return a populated ListItemCollection. Each state will have one ListItem in this collection where the Text member is the name of the state and the value member is the state's abbreviation. Add this class to your project.
Note that the StateList's constructor requires an ASNA database object be passed to it. This ensures that the StateList class won't start a unique iSeries job when it's used.
Readers who have attended the ASNA Web class will recognize this class as
exactly the class we create in the ASP.NET dropdown exercise. Part of the beauty of using ListItems to populate Windows combo boxes is that this same class can be used to populate either Windows or Web applications.
Using System
Using System.Data
Using System.Web.UI.WebControls
BegClass StateList Access( *Public )
DclDB pgmDB DBName( "*Public/DG NET Local" )
DclDiskFile States +
Type( *Input ) +
Org( *Indexed ) +
Prefix( States_ ) +
File( "Examples/States" ) +
DB( pgmDB ) +
ImpOpen( *No )
BegFunc GetList Type( ListItemCollection ) Access( *Public )
DclFld Result Type( ListItemCollection ) New()
OpenData()
Read States
DoWhile ( NOT States.IsEof )
//
// Either of these may need a ToString().
//
Result.Add( *New ListItem( States_State.Trim(), States_Abbrev ) )
Read States
EndDo
CloseData()
LeaveSr Result
EndFunc
BegSr OpenData
If ( NOT pgmDB.IsOpen )
Connect pgmDB
EndIf
Open States
EndSr
BegSr CloseData
Close States
EndSr
BegConstructor Access(*Public)
DclSrParm pgmDB Type( ASNA.VisualRPG.Runtime.Database )
*This.pgmDb = pgmDB
EndConstructor
EndClass
Step 6. Declare a DB object in the Winform.
Add a DB object to your program's Win form. This DB object is intended to be the master DB in this program. References to it will be passed to any child class used by this program (to limit iSeries jobs).
DclDB pgmDB DBName( "*Public/DG NET Local" )
Step 7. Populate the combo box
In the form's Load event, add the following code. This code connects the form's DB object, populates the combo box using the StateList class and then sets the combo box's SelectedIndex property.
BegSr Form1_Load Access(*Private) Event(*this.Load)
DclSrParm sender Type(*Object)
DclSrParm e Type(System.EventArgs)
Connect pgmDB
// New the StateList class and call its GetList method.
cboStates.DataSource = *New StateList( pgmDB ).GetList()
// Set the DisplayMember and Value members for the combo box.
cboStates.DisplayMember = "Text"
cboStates.ValueMember = "Value"
If ( cboStates.Items.Count > 0 )
cboStates.SelectedIndex = 0
EndIf
EndSrIn the code above, this line:
cboStates.DataSource = *New StateList( pgmDB ).GetList()
deserves a little discussion. What's happening here is that the StateList class is newed inline, and then its GetList method is called immediate from that inline instance of StateList. This technique doesn't require an intermediate variable to hold a class reference. For example, compare it to the more verbose technique:
DclFld sl Type( StateList ) New( pgmDB )
cboStates.DataSource = sl.GetList() Note that in either case, the DB object must be passed to StateList's constructor.
Step 8. Work with the selected value.
This code shows how to fetch the combo box's selected value.
BegSr btnShowSelected_Click Access(*Private) Event(*this.btnShowSelected.Click)
DclSrParm sender Type(*Object)
DclSrParm e Type(System.EventArgs)
MsgBox ( cboStates.SelectedItem *As ListItem ).Value
EndSrThis code is using inline casting and could also have been written like this:
DclFLd li Type( ListItem )
li = cboStates.SelectedItem *As ListItem
MsgBox li.Value No matter how you do, it's important that the SelectedItem be cast as a ListItem.
Step 9. Disconnect the master DB
When the form closes, don't forget to disconnect the DB.
BegSr Form1_FormClosing Access(*Private) Event(*this.FormClosing)
DclSrParm sender Type(*Object)
DclSrParm e Type(System.Windows.Forms.FormClosingEventArgs)
Disconnect pgmDB
EndSr