I have read the documentation on CellTextPaint but that is an ‘event’ and doesn’t work (I don’t think) the way I need.
What I’m trying to do is to get the row/column from CellClick to tell me what row the user has clicked on, and then redraw the existing black text within that ListBox row to red. The effect being that when the user clicks on a ListBox row the text in that row changes from the default black to red.
If I were to make up my own command to do this it would say something like “Listbox1.Cell(row,column).TextColor = &cFF0000” and I would place it in the CellClick event for the listbox.
Use the ListBox.Selected property in the CellTextPaint event to detect whether the cell being painted belongs to a currently selected row:
Event CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean
If Me.Selected(row) Then
// draw the text yourself
g.ForeColor = &cFF000000
g.DrawString(Me.Cell(row, column), x, y)
Return True
Else
Return False
End If
End Function
If you want to do this with a row that isn’t selected (but was clicked on) then you’d need to store the row number from the click event and then retrieve it in the CellTextPaint event.
Store the Row and Column parameters from the CellClick event (e.g. as properties of the window) and then compare them to the Row and Column parameters of the CellTextPaint event.
I guess I could just try it, but if a row is already selected (because a different cell on that row was already clicked) I am not sure CellTextPaint would fire on all platforms as in normal operation nothing would need to be repainted .
And even if it works now, it might not in the future if more drawing optimization is ever done on the listbox.
To be sure in the cell is aways redrawn in CellClick I would would do:
If me.Selected(row) Then ' A cell in that row was already clicked on
If LastRow = row And LastColumn = column Then Return False ' Same as last Cell clicked on
me.InvalidateCell(row,column) ' Make sure selected cell always gets redrawn
me.InvalidateCell(LastRow, LastColumn) ' Make sure the prior cell selected always gets redrawn
End if
LastRow = row
LastColumn = column
Also In CellTextPaint I would let the framework draw the text and just set the color:
If row = LastRow And column = LastColumn And Me.Selected(row) Then
g.ForeColor = &cFF000000
End If
Andrew’s method works very nicely … It colors the row that was clicked perfectly. But when you click another row the previously clicked row reverts back to black text.
I forgot to give one more parameter.
I would like for the rows that have been clicked to remain red to tell the user which rows have been clicked on so far.
[quote=434018:@Marc Speth]Andrew’s method works very nicely … It colors the row that was clicked perfectly. But when you click another row the previously clicked row reverts back to black text.
I forgot to give one more parameter.
I would like for the rows that have been clicked to remain red to tell the user which rows have been clicked on so far.
Is there a way to do that?[/quote]
Retain a list of previously clicked rows either in an array or a dictionary.
Sorry if this sound harsh but it’s IMO it’s true…
Given everything in this the thread, you should be able to figure that out yourself. Giving you more specifics at this point will hurt you more than help you in the long run.
I have tried to change the cell text color for a range of cells inside CellClick event. But where the CellTextPaint event passes g, the graphics object, to you, as well as Row, Column, X, and Y, the CellClick event doesn’t. Therefore I have to supply these myself.
Row and Column are easy. X and Y I can guess from the experiments I did in the CellTextPaint event. But so far I have not been successful at getting the graphics object for the ListBox, or perhaps the Cell.
Even if I put Dim ‘g As Graphics’ at the beginning of the CellClick event, when it tries to execute the:
g.ForeColor = &cFF000000
g.DrawString(Me.Cell(row, column), x, y)
… commands I get the Nil Object error because I don’t know how to get the graphics property of the ListBox, or Cell, or perhaps Row to be passed to those command lines.
I have also tried forcing a Select for a row in software, thereby forcing a redraw of that row, thereby triggering a text recolor for that row in CellTextPaint. But so far it appears that Select is can only be ‘passed’ and not ‘forced’.
You need to treat the events as completely separate. In CellClick, you record the row/column and then invalidate the listbox. That causes the CellTextPaint events to fire. In CellTextPaint, you check each cell against your list of cells and set the color accordingly. There are many ways to store the row/column of the clicks. Tell us what you have tried, and we can guide you from there.
In cellClick you can add the row to a list property in the window ClickedRows(-1) as integer then call invalidateCell(row,column) to cause it to repaint.
In the celltextPaint, check the list for the row.
If ClickedRows.indexof(Row) > -1 then g.forecolor=&cff0000
You can’t access the Graphics property of a control, except as it is passed to you in an event.
I first started programming in 1978 in the days of Fortran and BASIC linear programming. So wrapping my head around the concept Objects, Inheritance, and Events has proven to be a significant challenge for me.
I come from the days when if you wanted something to be displayed on the screen you typed '10 PRINT “This is what I want on the screen.” And if you wanted to erase it you used VTAB and HTAB to get back to that position on the screen and then issued a '30 PRINT " " ’ to print blank spaces over it. There was no ‘canvas’ and graphics properties that you had to DRAW into.
So this has been an uphill battle for me to retrain my brain.
Darn! I wanted to give both Tim AND Jim credit for solving my problem because it was the combined information from both posts that led me to the solution.
But the system will only let me click on one “this solved my problem”.
Go to the ListBox documentation and read the docs about each event, property, and method. I had to do that a few times but eventually it stuck (or some of it did, anyway).