xbrowse : enhancement , inline editing

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

xbrowse : enhancement , inline editing

Post by demont frank »

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
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

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
demont frank
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Post by demont frank »

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


# 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"

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

Post by James Bott »

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
demont frank
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Post by demont frank »

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
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post by James Bott »

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
demont frank
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Download link

Post by demont frank »

I provided a download link at :


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

Frank
Post Reply