LVN_ITEMCHANGED event triggered multiple times on single click

Started by Dan English, October 19, 2012, 11:51:20 AM

Previous topic - Next topic

Dan English

Would anyone know why a listview might trigger the LVN_ITEMCHANGED event 3 times on a single click?

I'm not doing any FF_ListView_SetSelectedItem calls on the listview, and I don't have any code in place to mess with my mouse clicks...

Dan English

Here's a bit more detail...

I have a listview where there's several rows populated.  Each represents a single record in a database.  The form for the record appears to the right of the listview.  If any of the form fields are updated, the program knows there's pending changes to be saved.

If the user clicks another listview row while changes are pending, the user needs to be prompted to save the changes first.  Here's the pseudo code to demonstrate what I'm doing:


Function FORM1_LISTVIEW1_LVN_ITEMCHANGING ( ... ) As Long

    ' show "do you want to save your changes?" messagebox:
    ' - if YES, save record and return %FALSE
    ' - if NO, don't save record and return %FALSE
    ' - if CANCEL, don't save record and return %TRUE (which cancels LVN_ITEMCHANGED)

End Function

Function FORM1_LISTVIEW1_LVN_ITEMCHANGED ( ... ) As Long

    If IsTrue (@lpNMV.uNewState And %LVIS_SELECTED) Then
        ' load record for selected row...
    End If

End Function


Is this the right way to handle this sort of situation?

Dan English

A further observation:  LVN_ITEMCHANGING is also triggered 3 times on clicking a listview row...

Paul Squires

Chris posted this several years ago to show what messages get posted when the mouse button is clicked:

Mouse Button Down:

NM_RELEASEDCAPTURE
LVN_ITEMCHANGING           (state changes for item unselected)
LVN_ITEMCHANGED
LVN_ITEMCHANGING
LVN_ITEMCHANGED
LVN_ITEMCHANGING          (state changes for item selected)
LVN_ITEMCHANGED
NM_CUSTOMDRAW

Mouse Up:

I guess that's why you need to check the new state flag.
Paul Squires
PlanetSquires Software

Dan English

Thanks, I guess that confirms what I've been seeing.

Is there an alternative way to deal with prompting the user to save changes when they change the listview row?

Paul Squires

This is a question which I thought would have an easy answer but I am having a hard time trying to figure out the answer. It seems like it should be easy....

I tried a few combinations of canceling the change while using PostMessage with a user defined message to pop up a message box confirmation and then manually set the row if the user decides to continue. No success. I googled this problem and it seems other are having similar problems. Not sure what the answer is at this point. Maybe I am missing something obvious.
Paul Squires
PlanetSquires Software

Paul Squires

Paul Squires
PlanetSquires Software

Christian Weilguny

Hi

I had the same problem.

My solution is this:

   Case %WM_Notify               
                   NMList = lParam
                   Select Case @NMList.Hdr.Code
                     Case %LVN_ITEMCHANGING                                             
                        If (@NMList.uChanged And %LVIF_STATE) = %LVIF_STATE Then
                           If (@NMList.uOldState And 1) = 1 Then                             
                              If IsTrue(VerifyChange(hWnd)) Then Function = %True: Exit Function
                           End If
                        End If
                   End Select                 


When the change is stopped with function = %True: Exit Function then the message comes a second time. I have catched this in the VerifyChange -Routine with a static variable:

Function VerifyChange(hWnd As Long) As Long
   Static bChg As Long
   
   If IsTrue(IsDirty(hWnd)) Then
      If IsTrue(bChg) Then
         bChg = %False: Function = %True: Exit Function
      End If
      Select Case MsgBox("Ã,,nderungen übernehmen?", %MB_ICONWARNING Or %MB_YESNOCANCEL Or %MB_DEFBUTTON1 Or %MB_APPLMODAL, "Datensatz geändert")
         Case %IDYES   : SyncToBrowser hWnd
         Case %IDCANCEL: bChg = %True: Function = %True: Exit Function       
      End Select                         
   End If                           

End Function


Maybe this is helpful.

Christian

Paul Squires

Thanks Christian! Appreciate your code. Hope it works to fix Dan's problem.

Paul Squires
PlanetSquires Software

Christian Weilguny

Hi Paul,

thanks for the honor,

something new about my option-button problem?

Christian

Dan English

Thanks guys...  I've since moved on to a different form design to avoid this situation, but I'm quite sure I'll run into this again.  I'll give it a shot when that time comes!