Prevent Checkbox field in Listbox from being changed

I feel stupid asking this because it seems like it should be an easy answer. But I can’t find it.

I want to prevent “editing” a checkbox field in a listbox. Seems like if the Listbox CellType is a checkbox it’s always editable (meaning you can change the state of the checkbox). Setting the cell to any other type results in the checkbox going away.

So you can easily prevent the text in a Listbox field from being changed, but it seems like checkboxes are always able to be changed.

I’m working on preventing the ability to change the state of the checkbox in other ways but figured I’d ask here as maybe there’s an easy way to do it.

Return True from CellClick?

Possibly only when over the checkbox region…

[code]Function CellClick(row as Integer, column as Integer, x as Integer, y as Integer) As Boolean

if me.CellType(row, column) = Listbox.TypeCheckbox then
if x < 25 then return true
end

End Function[/code]

Well, returning true from CellClick does indeed prevent it but I need to make an “editable” vs. “non-editable” state.

Right now I set the CellTag to True if I want the checkbox to be editable and set it to false if not. But I figured there might be an easier or cleaner way…

You have to store the editableness state someplace. If the state is listbox wide use a single property instead of CellTags.

if (x < 25) and (not self.allowCBEditing) then return true

It’s on a case by case basis. I’m creating a user list and want the fields changeable only when editing the user. So CellTag is really most appropriate.

Now the problem is when to set the value to false. If done in the action event, then once you click the checkbox, you are done. No changing your mind. So I thought maybe in CellLostFocus. It appears that CellLostFocus doesn’t fire for checkbox cells. Maybe the cell never gets the focus?

Yeah, I don’t know. I’m not clear on your UI. When you start editing the user set them true and when you stop editing set false. I don’t get why changing user data would change the editableness.

In Listbox.MouseDown event you can check if the column (and row eventually) are the ones you don’t want to be updated and simple return True.
You can be smarter and just set the Listbox.Listindex to that row, just to emulate selecting the line.

If the current user is not being edited, then I don’t want the checkbox to be able to be changed. Unlike textfields in list boxes, checkbox fields are always editable.

[quote=280152:@Massimo Valle]In Listbox.MouseDown event you can check if the column (and row eventually) are the ones you don’t want to be updated and simple return True.
You can be smarter and just set the Listbox.Listindex to that row, just to emulate selecting the line.[/quote]

I think that’s it! Let me mess with that idea and see… :slight_smile:

That’s that same as CellClick except you don’t get the row, column and local coordinates provided.

Yes, just filter out those clicks when the CellTag is False. I don’t see the problem still :stuck_out_tongue:

It is that’s true. And the more I think about it, determine wether or not to edit the cell is not the issue. It’s determining how/when to set it NOT to edit that is my challenge.

Well, my question is effectively answered - there’s no way within the listbox as it exists today, to deny a user from editing a checkbox cell. You have to code that in yourself.

It shouldn’t be too hard to create a Listbox subclass that adds a CellCheckBoxIsEditable(row, column) property. But yeah, there’s nothing built in. And filtering on some hard coded values is an incomplete hack.

Well, there might be a better way than click filtering. In CellAction, if the checkbox isn’t editable then flip it back. I thought there’d be a visual flicker with this but on mac at least it doesn’t.

[code]Sub CellAction(row As Integer, column As Integer)

me.CellCheck(row, column) = not me.CellCheck(row, column)

End Sub
[/code]

Here’s a class adding that option. Takes over CellTag so that’s made Private (there’s a way to re-expose CellTag if needed). allowCBEditing is initially true. Several edge cases left but depending on your needs could be easy to finish.

[code]Private Function CellTag(row As Integer, column As Integer) As Variant
break
End Function

Private Sub CellTag(row As Integer, column As Integer, Assigns _value As Variant)
break
End Sub

Function allowCBEditing(row As Integer, column As Integer) As boolean
dim v As Variant = super.CellTag(row, column)
return v = nil
End Function

Sub allowCBEditing(row As Integer, column As Integer, Assigns _value As boolean)
if _value then
super.CellTag(row, column) = nil
else
super.CellTag(row, column) = false
end
End Sub

Sub CellAction(row As Integer, column As Integer)
if (CellType(row, column) = Listbox.TypeCheckbox) and (not allowCBEditing(row, column)) then
CellCheck(row, column) = not CellCheck(row, column)
else
RaiseEvent CellAction(row, column)
end
End Sub

Event CellAction(row As Integer, column As Integer) //Event Definition
[/code]

Switch to this class and your Listbox has an allowCBEditing(row, column) setting which does just that. I think :slight_smile: Maybe it flickers on Windows :frowning: