Page 1 of 1
DCBROWSE with showing / hiding columns
Posted: Wed Jan 08, 2014 4:05 am
by reganc
Hi all
We have a screen that we import a set of product data into from various suppliers. After reading the data, we show the array of imported data using a simple DCBROWSE.
As each supplier will supply a different set of data, there could be between 2 and 50 fields of data read.
The DCBROWSE to show the imported data is built into the main import dialog, so all 50 columns are added to the getlist when the dialog is built.
I would like to only show the fields relevant to the actual data imported, so I was thinking of hiding the columns have not had data imported into.
I have an array of logical values for each column which holds a TRUE if a column has had data imported into it and I added a HIDE clause on each column that references the contents of that array.
This works but the column hiding done when the display is refreshed is visible. And by visible, I mean you can see it shifting the columns around. If this process were relatively fast, I may not have any issue with it. But unfortunately it is painfully slow.
So my question is:
Is there a way to have the column showing / hiding process happen without it being visible?
Alternatively, is there a way of creating the DCBROWSE on the fly after the data is read? I know there has been a thing mentioned about adding objects to a getlist after a dialog has been built but I have no knowledge of that or any disadvantages / pitfalls related to it.
Can anyone help?
Re: DCBROWSE with showing / hiding columns
Posted: Wed Jan 08, 2014 5:26 am
by Tom
I suggest to use AddColumn/DelColumn instead of the HIDE clause. It never worked correctly, and even it does, you may get problems with visual styles (headers) and other things.
So create the browse in a hidden dialog, delete the not used columns and show the dialog afterwards.
DCQUICKBROWSE may be an alternative.
Re: DCBROWSE with showing / hiding columns
Posted: Wed Jan 08, 2014 8:59 am
by rdonnay
I agree with Tom.
Hiding and showing columns is a bit complicated and doesn't always work good.
Re: DCBROWSE with showing / hiding columns
Posted: Wed Jan 08, 2014 9:11 am
by reganc
Thanks for the ideas, Tom.
Never used DCQUICKBROWSE. I can see that the clauses use arrays to build it so maybe it might be an easy option if what I have done cannot be refined/adjusted.
As for AddColumn/DelColumn, I wouldn't know where to start. My problem there is mixing it with the existing DC_xxx objects in the getlist.
I was thinking it would be easier for me to use DCREAD ... EXIT / SAVE with the dc_mergegetlist function to add objects but then I may have problems removing those merged getlist items / objects and adding new ones after.
Re: DCBROWSE with showing / hiding columns
Posted: Wed Jan 08, 2014 9:32 am
by reganc
rdonnay wrote:I agree with Tom.
Hiding and showing columns is a bit complicated and doesn't always work good.
Roger
Can you point me to the piece of code that handles the DCBROWSECOL ... HIDE functionality?
As far as I can see the native oColumn:hide() and oColumn:show() methods work fine except all they do is show / hide the column within the browse staticarea leaving the space/area in which they were shown as empty space between the visible columns.
And to fix this code would need to be added to walk through the static area childlist and reposition the visible columns, resize the staticarea and move the scrollbars as appropriate.
Or is there more to it than that?
Re: DCBROWSE with showing / hiding columns
Posted: Thu Jan 09, 2014 4:23 am
by reganc
I finally got something acceptable working.
I still use the HIDE clause on the DCBROWSECOL lines. The DCBROWSE itself has no HIDE clause. But it is the child of a DCSTATIC object which does have a HIDE clause.
I therefore hide() the browse object before the dc_getrefresh() and then show() it afterwards. I also added another static object with the caption 'please wait...' and show/hide this at the same time.
It may not be perfect but is visually less 'jarring' than having it visible while its doing its stuff.
I was really looking for a oBrowse:lockupdate() type fix as I thought that would be easy but this will have to do.
Re: DCBROWSE with showing / hiding columns
Posted: Thu Jan 09, 2014 5:17 am
by Cliff Wiernik
This is how we move columns. We have a static set of columns, same total, but display in different orders depending on the order.
Code: Select all
CASE nColumnFormat == 2
oBrowSearch:MoveColumn(1,6) // standard format #2, move column 6 right one column
oBrowSearch:MoveColumn(-3,9) // move column 9 left three columns
nColumnFormat := 3
Re: DCBROWSE with showing / hiding columns
Posted: Fri Jan 10, 2014 2:15 am
by reganc
Cliff Wiernik wrote:This is how we move columns. We have a static set of columns, same total, but display in different orders depending on the order.
Code: Select all
CASE nColumnFormat == 2
oBrowSearch:MoveColumn(1,6) // standard format #2, move column 6 right one column
oBrowSearch:MoveColumn(-3,9) // move column 9 left three columns
nColumnFormat := 3
I will keep this in mind. I suppose I could have just used this to shift the used columns to the left and left the others on the right side.
If the method I have used causes any problems I will try that instead.
Thanks.
Re: DCBROWSE with showing / hiding columns
Posted: Fri Jan 10, 2014 9:10 am
by rdonnay
Can you point me to the piece of code that handles the DCBROWSECOL ... HIDE functionality?
This is accomplished via the WhenHideEval() method of DC_XbpColumn() in _DCXBROW.PRG.
Code: Select all
* --------- This is from build 227. It works for John Lau,
* --------- The commented out version was from 232.
* --------- It didn't work for him. I don't know why.
* --------- I'd like to find a version that works for everyone
* --------- For now, wer'e going with this until somebody complains
METHOD DC_XbpColumn:WhenHideEval( lEnable, lShow, lProtect )
LOCAL oParent, nColumn, j, oColumn, nInsColumn, lOk
Grok(lShow)
IF Valtype(::hideBlock) = 'B'
oParent := ::parent
nColumn := ::columnPos
IF Eval(::hideBlock,self)
lOk := .f.
FOR j := 1 TO oParent:colCount
oColumn := oParent:getColumn(j)
IF oColumn:columnPos == nColumn // column has not been deleted
lOk := .t.
EXIT
ENDIF
NEXT
IF lOk
oParent:lockUpdate(.t.)
IF !Empty(oParent:freezeLeft)
oParent:setLeftFrozen({})
ENDIF
oParent:delColumn(j)
ENDIF
ELSE
lOk := .t.
nInsColumn := 1
FOR j := 1 TO oParent:colCount
oColumn := oParent:getColumn(j)
IF oColumn:columnPos == nColumn // column is already in browse
lOk := .f.
EXIT
ELSEIF oColumn:columnPos < nColumn
nInsColumn := j
ENDIF
NEXT
IF lOk
IF nColumn > 1
nInsColumn++
ENDIF
IF oParent:colCount == 0
nInsColumn := 1
ENDIF
oParent:lockUpdate(.t.)
IF !Empty(oParent:freezeLeft)
oParent:setLeftFrozen({})
ENDIF
oParent:insColumn(nInsColumn, self)
ENDIF
ENDIF
IF lOk
IF !Empty(oParent:freezeLeft)
oParent:setLeftFrozen(oParent:freezeLeft)
ENDIF
oParent:lockUpdate(.f.)
oParent:forceStable()
oParent:refreshAll()
oParent:invalidateRect()
ENDIF
ENDIF
IF Valtype(::whenBlock) = 'B'
lEnable := Eval(::whenBlock,self)
IF lEnable
::enable()
ELSE
::disable()
ENDIF
ENDIF
IF Valtype(lProtect) == 'L' .AND. Valtype(::protectBlock) == 'B'
lProtect := Eval(::protectBlock,self)
ENDIF
RETURN self
Re: DCBROWSE with showing / hiding columns
Posted: Wed Jan 15, 2014 5:02 am
by reganc
rdonnay wrote:Can you point me to the piece of code that handles the DCBROWSECOL ... HIDE functionality?
This is accomplished via the WhenHideEval() method of DC_XbpColumn() in _DCXBROW.PRG.
....
oParent:lockUpdate(.f.)
oParent:forceStable()
oParent:refreshAll()
oParent:invalidateRect()
....
Shouldn't the lockupdate(.f.) line be immediately before the invalidaterect() line?