Try OpenEdge Now
skip to main content
GUI for .NET Programming
Binding ABL Data to .NET Controls : Understanding the ProBindingSource : Data binding examples : ProDataSet binding example
 
ProDataSet binding example
ProDataSetBinding.p uses a ProBindingSource to bind a ProDataSet to a hierarchical grid. First, the procedure creates the ProDataSet. Then, it creates the ProBindingSource. It binds the grid to the ProBindingSource through the grid's DataSource property. Finally, it sets up some text boxes and binds them to display particular fields from the Customer table.
/* ProDataSetBinding.p
   Bind to a ProDataSet for the Customer and Invoice tables then display the
   records hierarchically in an Infragistics UltraWinGrid. */

/* USING statements must be the first in the procedure. Note that you could
   have USING statements for the OpenEdge classes also.*/
USING System.Windows.Forms.*.
USING Infragistics.Win.UltraWinGrid.*.

DEFINE VARIABLE rMainForm      AS Progress.Windows.Form       NO-UNDO.
DEFINE VARIABLE rCustInvGrid   AS UltraGrid                   NO-UNDO.
DEFINE VARIABLE rCustNumTB     AS TextBox                     NO-UNDO.
DEFINE VARIABLE rCustNumLabel  AS Label                       NO-UNDO.
DEFINE VARIABLE rCustNameTB    AS TextBox                     NO-UNDO.
DEFINE VARIABLE rCustNameLabel AS Label                       NO-UNDO.
DEFINE VARIABLE rSalesRepTB    AS TextBox                     NO-UNDO.
DEFINE VARIABLE rSalesRepLabel AS Label                       NO-UNDO.
DEFINE VARIABLE rCommentTB     AS TextBox                     NO-UNDO.
DEFINE VARIABLE rComLabel      AS Label                       NO-UNDO.
DEFINE VARIABLE rBindS         AS Progress.Data.BindingSource NO-UNDO.
DEFINE VARIABLE rControls      AS Control+ControlCollection   NO-UNDO.

DEFINE VARIABLE hTTCustomer    AS HANDLE                      NO-UNDO.
DEFINE VARIABLE hTTInvoice     AS HANDLE                      NO-UNDO.

DEFINE VARIABLE hDataSet       AS HANDLE                      NO-UNDO.
DEFINE VARIABLE hBufTTCust     AS HANDLE                      NO-UNDO.
DEFINE VARIABLE hBufTTInv      AS HANDLE                      NO-UNDO.
DEFINE VARIABLE hTopQuery      AS HANDLE                      NO-UNDO.

DEFINE TEMP-TABLE ttCustomer NO-UNDO LIKE Customer.
DEFINE TEMP-TABLE ttInvoice  NO-UNDO LIKE Invoice.

DEFINE DATASET dsCustInv FOR ttCustomer, ttInvoice
  DATA-RELATION FOR ttCustomer, ttInvoice RELATION-FIELDS(CustNum, CustNum).

hDataSet    = DATASET dsCustInv:HANDLE.

hTTCustomer = TEMP-TABLE ttCustomer:HANDLE.
hTTInvoice  = TEMP-TABLE ttInvoice:HANDLE.

hBufTTCust  = hTTCustomer:DEFAULT-BUFFER-HANDLE.
hBufTTInv   = hTTInvoice:DEFAULT-BUFFER-HANDLE.

/* Define the data-sources */
DEFINE DATA-SOURCE dCust FOR Customer.
DEFINE DATA-SOURCE dInv FOR Invoice.

/* Attach the data-sources to the dataset buffers */
hBufTTCust:ATTACH-DATA-SOURCE(DATA-SOURCE dCust:HANDLE,?,?,?).
hBufTTInv:ATTACH-DATA-SOURCE(DATA-SOURCE dInv:HANDLE,?,?,?).

/* Fill the dataset using the data-sources */
hDataSet:FILL().

/* customer navigation query */
hTopQuery = hDataSet:TOP-NAV-QUERY(1).
hTopQuery:QUERY-PREPARE("PRESELECT EACH ttCustomer").
hTopQuery:QUERY-OPEN.

/* This makes all of Customer and Invoice fields available for display. */
rBindS = NEW Progress.Data.BindingSource(hDataSet, hBufTTCust, "*", "").

/* Alternatively, specify fields using the optional include-fields and
   except-fields lists. */
/* rBindS = NEW Progress.Data.BindingSource(hDataSet, hBufTTCust, "*",
         "ttCustomer.Address2,ttCustomer.Country,ttInvoice.CustNum"). */

/* Disable editing because procedure does not have event logic for changes. */
rBindS:AllowEdit                     = FALSE.
rBindS:ChildAllowEdit["ttInvoice"]   = FALSE.
rBindS:AllowRemove                   = FALSE.
rBindS:ChildAllowRemove["ttInvoice"] = FALSE.

/* Main block */
IF VALID-OBJECT(rBindS) THEN
  DO ON ERROR UNDO, LEAVE:

    rMainForm        = NEW Progress.Windows.Form().
    rMainForm:Width  = 700.
    rMainForm:Height = 560.
    rMainForm:Text   = "Customer & Invoice Form".

    rCustInvGrid            = NEW UltraGrid().
    rCustInvGrid:Left       = 10.
    rCustInvGrid:Top        = 10.
    rCustInvGrid:Width      = 660.
    rCustInvGrid:Height     = 420.
    rCustInvGrid:Text       = "Customer & Invoice Grid".
    rCustInvGrid:DataSource = rBindS.

    rCustNumLabel        = NEW Label().
    rCustNumLabel:Left   = 10.
    rCustNumLabel:Top    = 445.
    rCustNumLabel:Width  = 50.
    rCustNumLabel:Height = 15.
    rCustNumLabel:Text   = "Cust #:".

    rCustNumTB          = NEW TextBox().
    rCustNumTB:Left     = 60.
    rCustNumTB:Top      = 440.
    rCustNumTB:Width    = 25.
    rCustNumTB:Height   = 15.
    rCustNumTB:ReadOnly = TRUE.

    rCustNameLabel        = NEW Label().
    rCustNameLabel:Left   = 95.
    rCustNameLabel:Top    = 445.
    rCustNameLabel:Width  = 60.
    rCustNameLabel:Height = 15.
    rCustNameLabel:Text   = "Customer:".

    rCustNameTB          = NEW TextBox().
    rCustNameTB:Left     = 160.
    rCustNameTB:Top      = 440.
    rCustNameTB:Width    = 150.
    rCustNameTB:Height   = 15.
    rCustNameTB:ReadOnly = TRUE.

    rSalesRepLabel        = NEW Label().
    rSalesRepLabel:Left   = 320.
    rSalesRepLabel:Top    = 445.
    rSalesRepLabel:Width  = 60.
    rSalesRepLabel:Height = 15.
    rSalesRepLabel:Text   = "Sales Rep:".

    rSalesRepTB          = NEW TextBox().
    rSalesRepTB:Left     = 390.
    rSalesRepTB:Top      = 440.
    rSalesRepTB:Width    = 100.
    rSalesRepTB:Height   = 15.
    rSalesRepTB:ReadOnly = TRUE.

    rComLabel        = NEW Label().
    rComLabel:Left   = 10.
    rComLabel:Top    = 470.
    rComLabel:Width  = 75.
    rComLabel:Height = 15.
    rComLabel:Text   = "Comments".

    rCommentTB          = NEW TextBox().
    rCommentTB:Left     = 10.
    rCommentTB:Top      = 490.
    rCommentTB:Width    = 660.
    rCommentTB:Height   = 100.
    rCommentTB:ReadOnly = TRUE.

    controls = rMainForm:Controls.
    controls:Add(rCustInvGrid).
    controls:Add(rCustNumLabel).
    controls:Add(rCustNumTB).
    controls:Add(rCustNameLabel).
    controls:Add(rCustNameTB).
    controls:Add(rSalesRepLabel).
    controls:Add(rSalesRepTB).
    controls:Add(rComLabel).
    controls:Add(rCommentTB).

    /* Data bindings for text boxes. */
    rCustNumTB:DataBindings:Add("Text", rBindS, "CustNum").
    rCustNameTB:DataBindings:Add("Text", rBindS, "Name").
    rSalesRepTB:DataBindings:Add("Text", rBindS, "SalesRep").
    rCommentTB:DataBindings:Add("Text", rBindS, "Comments").

    WAIT-FOR Application:RUN(rMainForm).

    RUN cleanup.

END. /* Main block */

PROCEDURE cleanup:

/* Cleanup ProDataSet resources */

  rBindS:Dispose( ).

END PROCEDURE.
When this procedure runs, a form appears displaying a hierarchical grid and a simple details viewer, as shown in the following figure.
Figure 13. Grid bound to ProDataSet
As discussed in Binding to ProDataSets, you might need to display parent and child records in separate grids. MultipleBindings.p binds two ProBindingSource objects to the same ProDataSet to display parent and child records in separate grids. The internal procedure, CustPositionChanged, synchronizes the grids. The main block calls this procedure in response to the ProBindingSource's PositionChanged event. The procedure then synchronizes and refreshes the child grid.
/* MultipleBindings.p
   Bind two BindingSource objects to the same ProDataSet then display the
   parent/child records in separate grids. */

/* USING statements must be the first in the procedure */
USING System.Windows.Forms.*.
USING Infragistics.Win.UltraWinGrid.*.

DEFINE VARIABLE rMainForm   AS Progress.Windows.Form       NO-UNDO.
DEFINE VARIABLE rCustGrid   AS UltraGrid                   NO-UNDO.
DEFINE VARIABLE rInvGrid    AS UltraGrid                   NO-UNDO.
DEFINE VARIABLE rCustBindS  AS Progress.Data.BindingSource NO-UNDO.
DEFINE VARIABLE rInvBindS   AS Progress.Data.BindingSource NO-UNDO.
DEFINE VARIABLE rControls   AS Control+ControlCollection   NO-UNDO.

DEFINE VARIABLE hTTCustomer AS HANDLE                      NO-UNDO.
DEFINE VARIABLE hTTInvoice  AS HANDLE                      NO-UNDO.

DEFINE VARIABLE hDataSet   AS HANDLE NO-UNDO.
DEFINE VARIABLE hBufTTCust AS HANDLE NO-UNDO.
DEFINE VARIABLE hBufTTInv  AS HANDLE NO-UNDO.
DEFINE VARIABLE hCustQry   AS HANDLE NO-UNDO.
DEFINE VARIABLE hInvQry    AS HANDLE NO-UNDO.

DEFINE TEMP-TABLE ttCustomer NO-UNDO LIKE Customer.
DEFINE TEMP-TABLE ttInvoice  NO-UNDO LIKE Invoice.

DEFINE DATASET dsCustInv FOR ttCustomer, ttInvoice
  DATA-RELATION FOR ttCustomer, ttInvoice RELATION-FIELDS(CustNum, CustNum).

hDataSet    = DATASET dsCustInv:HANDLE.

hTTCustomer = TEMP-TABLE ttCustomer:HANDLE.
hTTInvoice  = TEMP-TABLE ttInvoice:HANDLE.

hBufTTCust  = hTTCustomer:DEFAULT-BUFFER-HANDLE.
hBufTTInv   = hTTInvoice:DEFAULT-BUFFER-HANDLE.

/* Define the data-sources */
DEFINE DATA-SOURCE dCust FOR Customer.
DEFINE DATA-SOURCE dInv  FOR Invoice.

/* Attach the data-sources to the dataset buffers */
hBufTTCust:ATTACH-DATA-SOURCE(DATA-SOURCE dCust:HANDLE,?,?,?).
hBufTTInv:ATTACH-DATA-SOURCE(DATA-SOURCE dInv:HANDLE,?,?,?).

/* Fill the dataset using the data-sources */
hDataSet:FILL().

/* Navigation query for Customer */
hCustQry = hDataSet:TOP-NAV-QUERY().
hCustQry:QUERY-PREPARE("PRESELECT EACH ttCustomer").
hCustQry:QUERY-OPEN().
hCustQry:GET-NEXT().

/* Navigation query for Invoice */
hInvQry = hDataSet:GET-TOP-BUFFER():GET-CHILD-RELATION():QUERY.
hInvQry:QUERY-OPEN().

/* Display all Customer fields in the grid. */
rCustBindS = NEW Progress.Data.BindingSource(hCustQry, "*", "").
/* Display all Invoice fields in the grid. */
rInvBindS  = NEW Progress.Data.BindingSource(hInvQry, "*", "").

/* Disable editing because procedure does not include event logic to handle
   changes. */
rCustBindS:AllowEdit   = FALSE.
rCustBindS:AllowRemove = FALSE.
rInvBindS:AllowEdit    = FALSE.
rInvBindS:AllowRemove  = FALSE.

/* Main block */
IF VALID-OBJECT(rCustBindS) AND VALID-OBJECT(rInvBindS) THEN
  DO ON ERROR UNDO, LEAVE:

    rMainForm        = NEW Progress.Windows.Form().
    rMainForm:Width  = 900.
    rMainForm:Height = 520.
    rMainForm:Text   = "Customer & Invoice Form".

    rCustGrid            = NEW UltraGrid().
    rCustGrid:Left       = 10.
    rCustGrid:Top        = 10.
    rCustGrid:Width      = 860.
    rCustGrid:Height     = 250.
    rCustGrid:Name       = "CustGrid".
    rCustGrid:Text       = "Customer Grid".
    rCustGrid:DataSource = rCustBindS.
    rCustGrid:TabIndex   = 1.

    rInvGrid            = NEW UltraGrid().
    rInvGrid:Left       = 10.
    rInvGrid:Top        = 270.
    rInvGrid:Width      = 860.
    rInvGrid:Height     = 200.
    rInvGrid:Name       = "InvGrid".
    rInvGrid:Text       = "Invoice Grid".
    rInvGrid:DataSource = rInvBindS.
    rInvGrid:TabIndex   = 2.

    rControls = rMainForm:Controls.
    rControls:Add(rCustGrid).
    rControls:Add(rInvGrid).

    rCustBindS:PositionChanged:Subscribe("CustPositionChanged").

    WAIT-FOR Application:RUN(rMainForm).

END. /* Main block */

RUN cleanup.

PROCEDURE CustPositionChanged:
/* When Position changes in CustGrid, synchronize and refresh InvGrid.
   Alternately, you could set the buffer's Auto-Synchronize attribute to
   TRUE.*/

  DEFINE INPUT PARAMETER rSender AS Progress.Data.BindingSource NO-UNDO.
  DEFINE INPUT PARAMETER rArgs   AS System.EventArgs            NO-UNDO.

  hBufTTCust:SYNCHRONIZE().
  rInvBindS:RefreshAll().

END PROCEDURE.

PROCEDURE cleanup:
/* Cleanup ProDataSet resources */
  rInvBindS:Dispose( ).
  rCustBindS:Dispose( ).
END PROCEDURE.
When this procedure runs, a simple form appears displaying a customer grid and an invoice grid, as shown in the following figure.
Figure 14. Multiple grids bound to same binding source