NotifyPropertyChange

Aug 23, 2015 at 12:40 PM
Edited Aug 23, 2015 at 2:53 PM
Both classes DBServer4DB and DBFRecord need the following addition (marked with // !!!!!!!!):

DBServer4DB:
 /// We write through into the dbf table and signal the rest of the world, that we have changed something-
METHOD FIELDPUT( uField, uValue )

    LOCAL fieldPos AS INT         
    fieldPos := SELF:FieldPos( uField )

    LOCAL retVal AS USUAL
    retVal := SUPER:FIELDPUT( fieldPos, uValue )

    IF !(uValue == retVal) // !!!!!!!!!!!!!!!!!!! nicht 'uValue != retVal' !!!
        SELF:OnFieldChange(SELF:RecNo,fieldPos)   
        SELF:OnDataChange()
    ENDIF // !!!!!!!!!!!!!!!!!!!!!!

RETURN retVal

DBFRecord:
 /// The modern way to access an indexed property. This allows us to access the xth column of
 /// a dbf ( from the parent server ) by expression like self[x]. We will see later on that the
 /// class which is representing a column value holds the corresponding column number,
PROPERTY  SELF[fieldPos AS INT] AS OBJECT
    GET
...
    END GET

    SET
        LOCAL recno AS INT
        LOCAL repos:=FALSE AS LOGIC
       /// Check if the current record number of the dbf server is the expected one.
       /// If this is not the case position the dbf to the correct position.
        recno := SELF:_ParentServer:RecNo
        IF recno > 0
            repos := (recno != SELF:RecordNumber)
            IF repos
                SELF:_ParentServer:GoTo( SELF:RecordNumber )
            ENDIF
           // we do not want to be informed as this would leed to a recursion
            _ParentServer:FieldChanged -= NotifyFieldChange{ SELF , @FieldChange() }
           /// Now we can set the column value
        IF !(_ParentServer:FIELDGET(fieldPos) == VALUE ) // !!!!!!!!!!!!!!!!!!!!!!!! Nicht '(_ParentServer:FIELDGET(fieldPos) != VALUE )'   !!!
                _ParentServer:FIELDPUT(fieldPos,VALUE)
                SELF:OnPropertyChanged(fieldPos)
        ENDIF  // !!!!!!!!!!!!!!!!!!!!!!!!!!
        // we want to be informed again
            _ParentServer:FieldChanged += NotifyFieldChange{ SELF , @FieldChange() }
           /// Repsotion the dbf to the record we have been on before moving to the expected one.
            IF repos
                SELF:_ParentServer:GoTo(recno)
            ENDIF
        ELSE
            IF propsBacking:ContainsKey(fieldPos)
                propsBacking[fieldPos] := VALUE
            ELSE
                propsBacking:Add( fieldPos , VALUE )
            ENDIF
        ENDIF
    END SET

END PROPERTY

Hintergrund:
The NotifyFieldChangeEvent should be fired only, if the values has really changed. Otherwise to much unneeded events will be fired.

Pay attention: Must be !(X == Y) instead of X != Y. If the type is string comparision with "" is always true.

There will be dozens DBFRecords for one DBF row. These get all the events, even if they are 'dead' sind. On the long run, there will be a memory leak. Will investigate further how to resolve this.

I work with WPF and DataGrid.