Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Rhinorhino on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Is there an equivalent of "AfterRowColChange" in Listbox control? 1

Rajesh Karunakaran

Programmer
Joined
Sep 29, 2016
Messages
565
Location
MU
Hi Friends,

I have a list box whose RowSource is a cursor.
Is there an event in Listbox control equivalent to the "AfterRowColChange" event of a Grid control ?

My requirement is to show the value from the current record in a textbox below the listbox as the user go un and down in the listbox.

Thanks in advance
 
Hi Joe,

Yes, it's working!
Opps! my mistake. I knew, I saw it also but didn't try it before posting here 🤦‍♀️

Thanks
 
Hi,

To illustrate Joe's answer, please have a look a the code below

Code:
PUBLIC go_Form

go_Form=CREATEOBJECT("clsForm")
go_Form.Visible = .T.
go_Form.Show()

READ Events


CLOSE ALL
CLEAR ALL

************

DEFINE CLASS clsForm as Form

    AutoCenter = .T.
    Width = 420
    MinWidth = 420
    MaxWidth = 420
    Height = 360
    MinHeight = 360
    MaxHeight = 360
    ShowTips = .T.
   
   
    ADD OBJECT lblLabel as Label WITH Top = 6, Left = 6, Autosize = .T., ;
                Caption = "Name", Anchor = 3

    ADD OBJECT txtName as TextBox WITH Top = 30, Left = 258, Width = 90, Height = 24, ReadOnly = .T., Anchor = 3, ;
        DisabledBackColor = RGB(250, 250, 250), ToolTipText = "Name"

    ADD OBJECT txtNumber as TextBox WITH Top = 60, Left = 258, Width = 90, Height = 24, ReadOnly = .T., Anchor = 3, ;
        Alignment = 1, DisabledBackColor = RGB(250, 250, 250), ToolTipText = "ID"                                  
   
    ADD OBJECT txtGender as TextBox WITH Top = 90, Left = 258, Width = 90, Height = 24, ReadOnly = .T., Anchor = 3, ;
        DisabledBackColor = RGB(250, 250, 250), ToolTipText = "Gender"

    ADD OBJECT txtHeight as TextBox WITH Top = 120, Left = 258, Width = 90, Height = 24, ReadOnly = .T., Anchor = 3, ;
        DisabledBackColor = RGB(250, 250, 250), Alignment = 1, ToolTipText = "Height"

    ADD OBJECT cboBox as ComboBox WITH Top = 30, Left = 6, Width = 240, Height = 24, ;
            RowSourceType = 2, RowSource = "csrEmployees", Style = 2, Sorted = .T., ;
            Anchor = 3, ToolTipText = "Type name or click down arrow"
           
        PROCEDURE cboBox.Init()
            This.Value = csrEmployees.cName
           
            WITH ThisForm
                .txtName.Value = csrEmployees.cName
                .txtNumber.Value = csrEmployees.iNumber
                .txtGender.Value = csrEmployees.cGender
                .txtHeight.Value = csrEmployees.nHeight
            ENDWITH
           
            This.SetFocus()                

        ENDPROC
       
*!*    START of procedure that feeds the TextBoxes with their values

        PROCEDURE cboBox.Click()
       
            WITH ThisForm
                .txtName.Value = csrEmployees.cName
                .txtNumber.Value = csrEmployees.iNumber
                .txtGender.Value = csrEmployees.cGender
                .txtHeight.Value = csrEmployees.nHeight
            ENDWITH
       
        ENDPROC

*!*    END of the feeding procedure
   
        PROCEDURE cboBox.InterActiveChange()
       
            This.Click()
           
        ENDPROC

    PROCEDURE Load()
        CREATE CURSOR csrNames (cName c(8),iNumber I, cGender c(1), nHeight N(5,2))
       
        INSERT INTO csrNames VALUES ('Karl', 123, 'M', 1.75)
        INSERT INTO csrNames VALUES ('Robert', 124, 'M', 1.80)
        INSERT INTO csrNames VALUES ('Luisa', 125, 'F', 1.70)
        INSERT INTO csrNames VALUES ('Megan', 126, 'F', 1.68)
        INSERT INTO csrNames VALUES ('Georges', 127, 'M', 1.82)
        INSERT INTO csrNames VALUES ('Kim', 128, 'F', 1.65)
        INSERT INTO csrNames VALUES ('Paul', 129, 'M', 1.85)
        INSERT INTO csrNames VALUES ('Corinne', 130, 'F', 1.54)
        INSERT INTO csrNames VALUES ('Elisa', 131, 'F', 1.68)
        INSERT INTO csrNames VALUES ('John', 132, 'M', 1.72)
        INSERT INTO csrNames VALUES ('Frank', 133, 'M', 1.90)
       
        SELECT * FROM csrNames ORDER BY 1 INTO CURSOR csrEmployees      
    ENDPROC

    PROCEDURE Destroy()
        USE
        ThisForm.Release
        CLEAR Events
   
    ENDPROC
ENDDEFINE

************

hth

MarK
 
The grid has an active row, always one is a current row with the record pointer on it. The listbox has selected items, there can also be none selected or you can have multiselect, those are totally different concepts. The grid also has no value, neither single nor multiple in the sense there's a controlsource for twoway binding, every cell is a textbox with single value binding, but depends what control you put in a grid cell. The grid is always "binding" all it's cells to how many records and fields/columns the recordsource has or the grid has defined.

Well, good that InteractiveChange works for your case. It's not really something equivalent. InteractiveChange is about the change of value, which the grid kind of has not at all or for every cell, however you look at it.
 
Last edited:
For the record, InteractiveChange isn't the same as AfterRowColChange because it's only triggered when the control is changed, not when a row changes, but in your case, you said you wanted it to trigger when the user scrolled the values in the control.

The nice benefit of this is that those values aren't dependent on a row in a cursor.

Just remember the initial value will not trigger it unless you implicitly call it when the form loads.
 
Good points, Joe.

There's always a current "active" row in a workarea, independent of controls. And some controls actually only care about that row. Grid and Listbox also display other rows. And Listbox and Grid also have in common if you click on a cell or item that changes the current active row in the workarea. too. There's nno inverse, i.e. GO SKIP, SEEK or LOCATE to chenge record in a workarea doesn't make these the current value of a listbox and the grid doesn't even need to automatically scroll to that place, the active grid row can be off the visible area. And the grids AfterRowColChange only happens after the user interactively switches to another row or column, it doesn't occur for using the scrollbar, neither so in the listbox.

In short you don't have any thinkable ecvent that could be considerable to detect something, sometimes record specific events would be a nice thing to have. It could also open a can of worms of cascades of events just because you do a SCAN loop or you change record in an event and trigger it all over again. Surely a reason the VFP dev team didn't implement events like that.
 
For the record, InteractiveChange isn't the same as AfterRowColChange because it's only triggered when the control is changed, not when a row changes

Is this really true? I understand that InteractiveChange is triggered when the value in the control changes. Too, in my listbox as I said earlier, it works! So, I don't understand why you said, it's only triggered "when the control is changed" !
 
The interesting point about AfterRowColChange is what "Change" means.

It's not necessarily the value of a row or column that changed, but that your physical navigation position changed.

When you scroll through a Grid, your focus moves from row to row (record to record in a table or cursor), or column to column (fields in the same row), so it's triggered when you navigate, not because you changed a value.

Although it was the fit needed here, InteractiveChange is entirely different. Unlike a Grid, it does not scroll through any rows in a cursor, and the values can be any arbitrary source, including arrays, or arbitrary values added programmatically, so it's not bound to a table at all. In fact, the ControlSource simply be a simple value, but it can be empty and linked to nothing, and only referenced directly (Thisform.ThisListBox.Value).

So, when you select something in a ListBox, only the control changed (the Value property), but there's no requirement that a row in a table or cursor changed.
 
Hi,

Too, in my listbox as I said earlier, it works! So, I don't understand why you said, it's only triggered "when the control is changed" !

To emphasize what Joe said - when you scroll through a list/combo box its DisplayValue changes hence its Value, and this triggers InterActiveChange

hth

MarK
 
It's not necessarily the value of a row or column that changed
Yes, but a grid has no InteractiveChange event, it also has no single Value, it's a container for columns, which are a container for controls and not in the normal sense of container, but we'll just dig deeper into the quirks of word meanings in VFP properties and the programming language.

I was talking about the value change for InteractiveChange only, not merely for any "change", and as you describe the meaning here differs for the controls. The InteractiveChange and ProgrammaticChange have nothing to do with focus or positional change but value change of the controls that have those events, InteractiveChange for value changes by interaction of the user and ProgrammaticChange for value changes caused by code settting explicitly the value but also the ListIndex, for example.

Anyway, interacting with a textbox by moving the text cursor with array keys also causes no InteractiveChange event, because the stress is on change of value, not interaction. Likewise code changing the font or other properties also don't cause the ProgrammaticChange event, only direct or indirect value changes do. And so they are not an equivalent to the Grid AfterRowColChange at all and that they work for you as that must have to do with your actual intent being something else, Rajesh. You may even only look for the Valid or LostFocus event of controls, be it standalone controls or controls in a grid column and actually use the Grid AfterRowColChange just because it also occurs when the control changes. It's not a good programming style to just look out for "something that fires".
 
Last edited:
Yes, but a grid has no InteractiveChange event, it also has no single Value, it's a container for columns, which are a container for controls and not in the normal sense of container, but we'll just dig deeper into the quirks of word meanings in VFP properties and the programming language.

I was talking about the value change for InteractiveChange only, not merely for any "change", and as you describe the meaning here differs for the controls. The InteractiveChange and ProgrammaticChange have nothing to do with focus or positional change but value change of the controls that have those events, Interactive for value changes by interaction of the user and ProgrammaticChange for value changes caused by code settting explicitly the value but also the ListIndex, for example.
100% correct. ProgramaticChange is another important variation on potential triggers.

I just wanted to let the Rajesh know the primary reason they are not exactly interchangeable and why there is no AfterRowColChange event in a ListBox because there are no rows or columns. As you said, a grid is just a container, and each row can contain just about any control, each with its own events.

In a nutshell, the Before and AfterRowColChange events trigger when you move around the grid, whether there was a change or not which explains why it's not a direct equivalent of InteractiveChange, but it does exactly with Rajesh actually needed.
 

Part and Inventory Search

Sponsor

Back
Top