xbrowse : enhancement , inline editing

xbrowse : enhancement , inline editing

Postby demont frank » Fri May 02, 2008 12:27 pm

Hello,

Using the in line editing possibility's from fw , i see some problems :

1) In all mine dialog's i use a self made comboclass (xbrowse , btnget)
In xbrowse i have to use the fwh combo class .
Only get and listbox are possible
NO CHECKBOX ,BTNGET , DTEPICKER , BUTTON .........

2) bWhen ???????

3) Editing one cell , this must be written in the dbf. So we have one cyclus from rlock / append , dbunlock.

This cyclus is designed for : lock one record , edit all the fields and then write , not for one field.

3) ESCAPE works only on the current cell , not on the cells edited on the same row

Each from this points can be avoided :

1) The columns from the obrowse which should be edited :
Define the obj's as all the others from the dialog , checkbox , button , ... is possible . Also VALID , WHEN , FONT , ......

Last column : a checkbox or button as OK button (write the data)

ON INIT , hide this object's

2) oBrw:bKeydown and oBrw:lDoubleClick are set to activate this objects , and to deasactivate all the others

The column objects are moved and resized as needed

3) Activating the OK button (or checkbox) write the data in the browse and dbf . Pressing escape before this button cancel the operation.
The column objects are hidden , others enabled

Maybe the code must be better designed , but i have a working example.
Works also when columns are scrolled , or when columns are changed.

Can be send on demand , or when someone is intrested , published here (only 400 lines off code + rc.file and some bmp-file (from fw directory) ).

Frank
demont frank
 
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Postby Antonio Linares » Tue May 06, 2008 5:49 am

Frank,

Will you be so kind to publish your code here ? many thanks

Also a download url for a working EXE would be of a great help. Thanks!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42084
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby demont frank » Tue May 06, 2008 8:46 am

XBROWSE : INLINE EDITING

1) For each column which must be edited , add this control to your dialog with the same syntax from the other controls
oCol:bOnPostEdit can be set. If not it receives a default value (only browse is updated)
Can also be set with SetPostEdit(oBrw,Arrayindex,Fieldindex)

In your browse add a column (Logical value , set on .T.) and define a checkbox and ON CHANGE as in EditDbf (line 122)
Not tested , but a button should also be possible

2) Set oBrw:bPastEof() , oBrw:lDblClick and obrw:bKeydown (see EditDbf.prg , prg-file , line +/- 130)

3) On init hide the controls from the browse

Editing a row can be interupted with Escape
Changes are only written with the OK checkbox

That is all

Frank Demont

Notes

Fastedit mode is only activated when also oCol:nEdittype is set
From all other data used to edit the column is only bPostEdit used





Code: Select all  Expand view

# include "fivewin.ch"
# include "xbrowse.ch"
# include "Common.ch"
# include "dtpicker.ch"
# define CLR_1 nRGB( 190, 215, 190 )
# define CLR_2 nRGB( 230, 230, 230 )

FUNCTION MAIN(cDbfFile)
***********************
LOCAL aStruct , lTest := .F.
LOCAL i , j
LOCAL aCountry
LOCAL oWnd , oBmp
IF IsNil(cDbfFile)
   cDbfFile := "Demo.Dbf"
   lTest := .T.
END
IF ! "." IN cDbfFile
   cDbfFile += ".dbf"
END
IF ! File(cDbfFile)
   aStruct := {{"Name","C",25,0},{"Number","N",10,2},{"Country","C",3,0},{"Maried","L",1,0},{"Date","D",8,0}}
   DbCreate(cDbfFile,aStruct)
   USE (cDbfFile)
   aCountry := {"BE ","NL ","FR "}
   j := 1
   FOR i := 1 TO 20
      APPEND BLANK
      REPL FIELD->Name WITH PAD("Name " + LTRIM(STR(i)),25)
      REPL FIELD->Number WITH i*1000
      REPL FIELD->Country WITH aCountry[j++]
      REPL FIELD->Maried  WITH ( i%2 == 0 )
      REPL FIELD->Date    WITH Date() + i
      IF j > 3
         j := 1
      END
   NEXT
   USE
END
USE (cDbfFile) SHARED
    DEFINE WINDOW oWnd TITLE "Edit Dbf" ;
      MENU BuildMenu( oWnd ) MDI ;
      MENUINFO 3

   DEFINE BITMAP oBmp RESOURCE "Background"

   SET MESSAGE OF oWnd TO FWVERSION + ", " + FWCOPYRIGHT CENTERED TIME DATE

   oWnd:bPainted = { | hDC | BmpTiled( hDC, oWnd, oBmp ) }

   ACTIVATE WINDOW oWnd

return nil

//----------------------------------------------------------------------------//

function BuildMenu( oWnd )

   local oMenu

   MENU oMenu
      MENUITEM "Edit Dbf";
        ACTION EditDbf( oWnd )
   ENDMENU

return oMenu


CLOS ALL
RETURN
********************************************************************************************************************************
PROC EditDbf(oWnd)
**************
LOCAL Arr[0]
LOCAL oDlg , oBrw , oBut
LOCAL aObj[3]
LOCAL i
LOCAL el := {SPACE(25),1000,"BE ", .T. , Date() , .T. }
LOCAL aCountry := {"BE ","NL ","FR "}
LOCAL lNieuw := .F.
ReadDbfData(Arr)
DEFINE DIALOG oDlg RESOURCE "TEST" OF oWnd

   oBrw := TXBrowse():New( oDlg )
   //oBrw := TXBrowse():New( oWnd )

   oBrw:CreateFromResource( 101 )
   oBrw:nMarqueeStyle       := 3 //Highlight row //MARQSTYLE_HIGHLCELL
   oBrw:nColDividerStyle    := LINESTYLE_BLACK
   oBrw:nRowDividerStyle    := LINESTYLE_BLACK
   oBrw:lHScroll := .F. ////oBrw:lColDividerComplete := .t.
  oBrw:bClrStd := {|| {CLR_BLACK, iif( oBrw:nArrayAt() % 2 = 0, CLR_1, CLR_2  ) } }
   oBrw:bClrSelFocus := {||{CLR_WHITE, CLR_GREEN}}
  oBrw:nArrayAt := 1
   oBrw:nRowSel  := 1
   oBrw:nRowHeight := 25 //oBrw:nRowHeight*1.2
   oBrw:lFastEdit := .T.
  oBrw:SetArray( Arr  )

    FOR i := 1 TO LEN(Arr[1])
      oBrw:aCols[ i ]:cHeader = Field(i)
      IF IsLogical(Arr[1,i])
         oBrw:aCols[ i ]:nWidth = 20
         MakeBitmapCol(oBrw,i)
      END
    NEXT
    ATAIL(oBrw:aCols):Hide()
   IF ! __ObjHasData(oBrw:aCols[1],"OBRWOBJ")
      __OBJADDDATA(oBrw:aCols[1],"oBrwObj")
   END

   __objModMethod(oBrw:aCols[1],"Edit",@ActivateoBrwDlg(oBrw , oDlg))

    REDEFINE GET oBrw:aCols[1]:oBrwObj VAR el[1] ID 100 OF oDlg VALID ! EMPTY(el[1])
        oBrw:aCols[ 1 ]:nEditType := 1         // Fastedit works only when set!!!
    REDEFINE GET oBrw:aCols[2]:oBrwObj VAR el[2] ID 105 OF oDlg PICTURE "9999999.99"
   oBrw:aCols[ 2 ]:nWidth = 80
   oBrw:aCols[ 2 ]:nEditType := 1            // Fastedit !!!

    REDEFINE COMBOBOX oBrw:aCols[3]:oBrwObj VAR el[3] ITEMS aCountry;
      ID 110 OF oDlg

    REDEFINE CHECKBOX oBrw:aCols[4]:oBrwObj VAR el[4] ID 120 OF oDlg

   oBrw:aCols[ 5 ]:nWidth = 100
   REDEFINE DTPICKER oBrw:aCols[5]:oBrwObj VAR el[5] ID 130 OF oDlg

   oBrw:aCols[ 6 ]:cHeader = "OK"
   oBrw:aCols[ 6 ]:nWidth = 38
    REDEFINE CHECKBOX oBrw:aCols[6]:oBrwObj VAR el[6] ID 140 OF oDlg;
         ON CHANGE {||IIF(oBrw:aCols[6]:oBrwObj:Varget(),SaveoBrwDlg(oBrw,@lNieuw,oDlg,oBut),)}
    oBrw:aCols[6]:Hide()
FOR i := 1 TO FCOUNT()
   SetPostEdit(oBrw,i,i)
NEXT
OBrw:bPastEof() := {|| IIF( NewoBrwDlg(oBrw , @lNieuw) , (Sysrefresh() , ActivateoBrwDlg(oBrw , oDlg)) , ) }
oBrw:bLDblClick := {||ActivateoBrwDlg(oBrw , oDlg)}
oBrw:bkeyDown  := { | nkey |IIF(nkey==13 , ActivateoBrwDlg(oBrw , oDlg) , IIF(nKey==VK_DELETE , WisoBrwDlg(oBrw , @lNieuw) , ) ) }
REDEFINE BUTTON oBut ID 300 OF oDlg ACTION oDlg:End()// WHEN ! lNieuw

ACTIVATE DIALOG oDlg ;
   ON INIT ( AEVAL(oBrw:aCols,{|oCol|IIF(IsObJect(oCol:oBrwObj),oCol:oBrwObj:Hide(),) }) );
  VALID  IIF(GETKEYSTATE(VK_ESCAPE) , ( ActivateDlg(oDlg,oBrw,oBut,@lNieuw) , .F.) , .T. )

RETURN
********************************************************************************************************************************
PROC ReadDbfData(Arr)
*********************
LOCAL b , i
GO TOP
DO WHIL ! EOF()
   b := {}
   FOR i := 1 TO FCOUNT()
      AADD(b,Fieldget(i))
   NEXT
   AADD(b,.T.)
   AADD(b,Recno())
   AADD(Arr,b)
   SKIP
END
RETURN
********************************************************************************************************************************
PROC SetPostEdit(oBrw,i,j)
**************************
// i : Arrayindex ,  j : Field Index
oBrw:aCols[i]:bOnPostEdit  := {|o | x := o:oBrwObj:Varget() , oBrw:aArrayData[ oBrw:nArrayAt, i ] := x  ,  IIF(IsNil(j),,FieldPut(j,x)) }
RETURN
*****************************************************************************************************
PROC MakeBitmapCol(oBrw,i)
***************************
LOCAL oCol
LOCAL x
oCol := oBrw:aCols[i]
oCol:AddResource("CHECKON")
oCol:AddResource("CHECKOFF")
x := LEN(oCol:aBitMaps)
oCol:bBmpData   := {||IIF(IsLogical(oBrw:aArrayData[oBrw:nArrayAt,i]) , IIF(oBrw:aArrayData[oBrw:nArrayAt,i],x-1,x),0)}
oCol:bStrData   := {||" "}
RETURN
******************************************************************************************************
FUNC NewoBrwDlg(oBrw , lNieuw )
******************************
LOCAL Arr := {}
LOCAL x
LOCAL i
IF lNieuw
   RETURN .F.
END
GO 9999999   // EOF() !
Arr := {}
FOR i := 1 TO FCOUNT()
   x := Fieldget(i)
   IF ValType(x) = "D"
      x := Date()
   END
   AADD(Arr , x)
NEXT
AADD(Arr,.T.)      // Ok checkbox
AADD(Arr,0)        // RecNr 0 , record will be appended when the ok checkbox is clicked
AADD(oBrw:aArrayData,Arr)
oBrw:GoBottom()
oBrw:Refresh()
lNieuw := .T.
RETURN .T.
*****************************************************************************
PROC WisoBrwDlg(oBrw , lNieuw)
*********************************
LOCAL Nr := oBrw:NarrayAt
LOCAL RecNr := ATAIL(oBrw:aArrayData[Nr])
DbGoto(RecNr)
IF RLOCK()
   DbDelete()
   DbUnlock()
   aDel(oBrw:aArrayData,Nr,.T.)
   oBrw:nArrayAt := MIN(Nr,LEN(oBrw:aArraydata))
   oBrw:Refresh()
   IF lNieuw
      lNieuw := .F.
   END
END
RETURN
**********************************************************
PROC SaveoBrwDlg(oBrw , lNieuw , oDlg , oBut)
**********************************************
LOCAL Nr := oBrw:nArrayAt
LOCAL RecNr := ATAIL(oBrw:aArrayData[Nr])
LOCAL oCol , i
LOCAL lOk := .F.
FOR EACH oCol IN oBrw:aCols
   IF IsObject(oCol:oBrwObj) .AND. IsBlock(oCol:oBrwObj:bValid) .AND. ! EVAL(oCol:oBrwObj:bValid)
      oCol:oBrwObj:SetFocus()
      RETURN
   END
NEXT
IF lNieuw
   IF ! DBAPPEND()
      RETURN
   END
   RecNr := RecNo()
   ATAIL(oBrw:aArrayData[Nr]) := RecNr
END
DbGoto(RecNr)
FOR EACH oCol IN oBrw:aCols
   IF IsObject(oCol:oBrwObj) .AND. IsBlock(oCol:bOnPostEdit)
      i := Hb_EnumIndex()
      EVAL(oCol:bOnPostEdit,oCol)
   END
NEXT
oBrw:DrawLine(.t.)
DbCommit()
DbGoto(recnr)
lNieuw := .F.
DBUNLOCK()
ActivateDlg(oDlg,oBrw,oBut,.F.,@lNieuw)
oBrw:SetFocus()
RETURN
********************************************************************************************************************************
PROC ActivateoBrwDlg(oBrw,oDlg)
*******************************
LOCAL   nRow
LOCAL   nCol
lOCAL nWidth
LOCAL nHeight
LOCAL Nr   //:= oBrw:nArrayAt
LOCAL nKol //:= oBrw:nColSel
LOCAL x
LOCAL oCol , i , Obj , Gehi
LOCAL RecNr
LOCAL aDisPlay
LOCAL Self := HB_QSelf() , cKey , nKey
IF ! IsNil(Self)
   nKey := IIF(IsNumber(oBrw),oBrw,nil)
   oBrw := Self:oBrw
   oDlg := oBrw:oWnd
   IF isnumber(nKey)
     cKey := Chr( nKey )
   END
END
Nr   := oBrw:nArrayAt
nKol := oBrw:nColSel
RecNr := ATAIL(oBrw:aArraydata[Nr])
IF RecNr > 0
   DbGoto(RecNr)
   IF ! RLOCK()
      RETURN
   END
END
FOR EACH Obj IN oDlg:aControls
   Obj:Disable()
NEXT
nRow    := ( ( oBrw:nRowSel - 1 ) * oBrw:nRowHeight ) + oBrw:HeaderHeight() + 2 + oBrw:nTop
nHeight := oBrw:nRowHeight - 4
aDisPlay := oBrw:GetDisplayCols()
FOR EACH oCol IN oBrw:aCols
   IF IsObject(oCol:oBrwObj)
      i := Hb_EnumIndex()
      WITH OBJECT oCol
         nCol    := :nDisPlayCol + 2 + oBrw:nLeft
         nWidth  := :nWidth - 4
         x := oBrw:aArrayData[Nr,oCol:nCreationOrder]
         If oCol:cHeader = "OK"
            nCol := oBrw:nWidth + oBrw:nLeft + 2
            x := .F.
         END
         IF __ObjHasMethod(:oBrwObj,"VARPUT")  // BUTTON ???
            :oBrwObj:Varput(x)
            :oBrwObj:Refresh()
         END
         IF (i IN aDisplay) .OR. oCol:cHeader = "OK"
            IF (i IN aDisplay) .AND. i == aDisplay[1]     // Selected col (or clicked) is no edit column
               Obj := :oBrwObj
               Gehi := i
            END
            :oBrwObj:Enable()
            :oBrwObj:Move(nRow, nCol, nWidth, nHeight, .t. )
            :oBrwObj:Show()
            IF IsNil(:bOnPostEdit)
               SetPostEdit(oBrw,i)
            END
            IF i == nKol                                  // Selected col (or clicked)
               Obj := :oBrwObj
               Gehi := i
            END
         END
      END
   END
NEXT
IF ! IsNil(Obj)
   IF IsNumber(Gehi) .AND. IsNumber(nKey)
      oCol := oBrw:aCols[Gehi]
     If oBrw:lFastEdit .and. oBrw:nMarqueeStyle <= MARQSTYLE_HIGHLCELL .and. ;
            oCol:nEditType > 0 .and. ;
            ( IsAlpha( cKey ) .or. IsDigit( cKey ) .or. cKey == "-" )

         IF __ObjHasMethod(oCol:oBrwObj,"VARPUT")  // BUTTON ???
            x := oBrw:aArrayData[Nr,oCol:nCreationOrder]
            IF IsCharacter(x)
                  oCol:oBrwObj:bGotFocus := {|self|Self:Keychar(cKey) , Self:oGet:Pos := 2 , Self:EditUpdate() , self:Setpos(2),Self:bGotFocus:=nil}
            ELSEIF IsNumber(x)
               IF (48<=nKey .AND. nKey <= 57) .or. cKey == "-"
                  oCol:oBrwObj:bGotFocus := {|self|Self:Keychar(cKey) , Self:oGet:Pos := 2 , Self:EditUpdate() , self:Setpos(2),Self:bGotFocus:=nil}
                  oCol:oBrwObj:lClrFocus  := .T.
               END
            END
            oCol:oBrwObj:Refresh()
         END
      end
   END
   Obj:Setfocus()
END
RETURN
********************************************************************************************************************************
PROC ActivateDlg(oDlg,oBrw,oBut,lNieuw)
***************************************
LOCAL oCol , i , Obj
LOCAL Nr
LOCAL RecNr
IF oDlg:aControls[1]:lActive      // Can give problems when this contol is a oCol:oBrwObj !!!!!!!
   oBut:Setfocus()
   return
END
FOR EACH Obj IN oDlg:aControls
   Obj:Enable()
NEXT
FOR EACH oCol IN oBrw:aCols
   IF IsObject(oCol:oBrwObj)
      oCol:oBrwObj:Hide()
   END
NEXT
Nr := oBrw:nArrayAt
RecNr := ATAIL(oBrw:aArrayData[Nr])
IF RecNr == 0
   aDel(oBrw:aArrayData,Nr,.T.)
   oBrw:nLen := LEN(oBrw:aArrayData)
   oBrw:nArrayAt := MIN(oBrw:nArrayAt,oBrw:nLen)
   oBrw:GoBottom()
   oBrw:Refresh()
   lNieuw := .F.
ELSE
   DbGoto(RecNr)
   DbUnlock()
END
oBrw:setFocus()
RETURN
**********************************************************************************************
PROC Trace(...) // Only to test
*************
LOCAL i , el
LOCAL  tkst := ""
LOCAL arr := HB_aParams() , elem , hlp
FOR EACH el IN arr
      IF Valtype(el) == "A"
         FOR EACH elem IN el
            hlp := cValToChar(elem)
            IF IsCharacter(elem) .AND. LEN(elem) == 1 .AND. ASC(elem) < 32
               hlp := 'CHR('+LTRIM(STR(Asc(elem))) + ')'
            END
            tkst += CRLF + hlp
         NEXT
      ELSEIF ValType(el) == "H"
         FOR  i := 1 TO LEn(el)
            hlp := cValToChar(el[i])
            IF IsCharacter(Hlp) .AND. LEN(Hlp) == 1 .AND. ASC(Hlp) < 32
               hlp := 'CHR('+LTRIM(STR(Asc(Hlp))) + ')'
            END
            tkst += CRLF + PAD(HaaGetKeyAt(el,i),10) + " : " + hlp
         NEXT
      ELSE
         tkst += CRLF + cValToChar(el)
      END
NEXT
i := 0
DO WHIL ! EMPTY(PROCNAME(i))
   tkst += CRLF  + PROCNAME(i) + " " + "Lijn : " + LTRIM(STR(PROCLINE(i)))
   i++
END
? tkst
RETU
//----------------------------------------------------------------//
STATIC FUNCTION BmpTiled( hDC, oWnd, oBmp )

   local nWidth := oWnd:nWidth(), nHeight := oWnd:nHeight()
   local nRow := 0, nCol := 0, n
   local nBmpWidth  := oBmp:nWidth(),  nBmpHeight := oBmp:nHeight()

   if oBmp:hBitmap == 0
      return nil
   endif

   while nRow < nHeight
      nCol = 0
      while nCol < nWidth
         PalBmpDraw( hDC, nRow, nCol, oBmp:hBitmap )
         nCol += nBmpWidth
      end
      nRow += nBmpHeight
   end

return nil
**************************************************************
TEST DIALOG 6, 15, 450, 227
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "TXBrowse demo"
FONT 8, "MS Sans Serif"
{
CONTROL "", 101, "TXBrowse", 0 | WS_CHILD | WS_VISIBLE | WS_VSCROLL |  WS_TABSTOP, 4, 5, 328 , 202
EDITTEXT 100 , 197 , 2, 20, 10, WS_BORDER | WS_TABSTOP
EDITTEXT 105 , 197 , 2, 20, 10, WS_BORDER | WS_TABSTOP
COMBOBOX 110, 8, 16, 72, 75, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX " ", 120 , 230 , 235 , 80, 14, BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP  //, 8192
CONTROL "", 130 , "SysDateTimePick32", 0 | WS_CHILD | WS_VISIBLE | WS_TABSTOP | DTS_SHOWNONE , 153, 108 , 55, 10
CHECKBOX "OK  ", 140 , 230 , 235 , 32 , 14, BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP  //, 8192

PUSHBUTTON "OK",  300 , 252, 211, 50, 14
}

CHECKON  BITMAP "bitmap\Checkon.bmp"
CHECKOFF BITMAP "bitmap\Checkoff.bmp"
BACKGROUND BITMAP "bitmap\fiveback.bmp"

demont frank
 
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Postby James Bott » Wed May 07, 2008 9:23 am

Frank,

I think most users expect browses to work like a spreadsheet and there is no concept of having to check a checkbox to get the data updated. Most users are going to be very confused by this.

James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Postby demont frank » Wed May 07, 2008 1:58 pm

James,

For me is a row in a table a record. Editing it in a dialog we

Lock the record , or append it
Edit all the fields , with all kinds off controls , navigating with TAB or ENTER
A ok button accepts the data , inviting the user to check before , writes the data and unlock . Escape should eliminate the changes from the data .

You are right when you stated it is not the filosophy from excel, more these from Clipper (editing a record)


In mine program editing a row is as editing a dialog . In DOS i was used to do that . The ok checkbox can maybe be discarded (updating after each field , as in oCol:edit from txbrowse) ) , but :

LOCK , UNLOCK must for every field. Suppose that two users try to edit the same row . After editing the first field , the second can be blocked

ESCAPE : only the editing field

Navigating : No TAB or ENTER

When a row is edited , i am convinced that the user has the intention to edit not only one cell , but also the others


The greatest benefit is we can use all kinds off control , not only get and listbox

Frank
demont frank
 
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Postby James Bott » Wed May 07, 2008 7:01 pm

Frank,

>For me is a row in a table a record. Editing it in a dialog we

>Lock the record , or append it
>Edit all the fields , with all kinds off controls , navigating with TAB or >ENTER
>A ok button accepts the data , inviting the user to check before , writes >the data and unlock . Escape should eliminate the changes from the data.

Agreed, or, as I usually use, "optimistic" locking; edit, lock, save, unlock. This means the record is only locked for a split second.

>You are right when you stated it is not the filosophy from excel, more >these from Clipper (editing a record)

We do have to keep the users expectations in mind when designing our programs.

>In mine program editing a row is as editing a dialog . In DOS i was used >to do that . The ok checkbox can maybe be discarded (updating after >each field , as in oCol:edit from txbrowse) ) , but :

>LOCK , UNLOCK must for every field. Suppose that two users try to edit >the same row . After editing the first field , the second can be blocked

>ESCAPE : only the editing field

>Navigating : No TAB or ENTER

>When a row is edited , i am convinced that the user has the intention to >edit not only one cell , but also the others

These are all valid issues, and this is why I do not generally allow users to edit browses directly but rather use a double-click to bring up a dialog. There are other reasons too. A row of data is often too long to display on the screen at one time, but it will all fit on a dialog. Data can be grouped in a dialog and all kinds of controls can be used.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Download link

Postby demont frank » Sun May 18, 2008 6:29 am

I provided a download link at :


http://rapidshare.com/files/115712013/ROWEDIT.ZIP.html

Frank
demont frank
 
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: cmsoft and 90 guests