Tip: Access listbox columns by name

In the column-related events of a listbox, you are passed the column number to use. This can lead to hard to read code and can cause problems if you rearrange the columns. Code like this is a mess. It’s hard to read and hard to maintain:

if column = 0 then
   ...
elseif column = 1 then
   ...
etc.

Instead, use the column headings to refer to the columns.

select case me.Heading(column)
case "Customer"
   ...
case "Date"
   ...
case "Amount"
   ...
etc.

Thoughts?

I think constants would be safer, though the constants COULD be the header strings as long as the header values are also set in code with them, rather than in the inspector.

I think using displayed UI text directly is a bug waiting to happen… At some point the the displayed string may be changed and the code not updated… Never mind localization issues!

  • Karen

I use the ColumnTag property to hold the column names.

I would not use Heading() as that’s localized.

Constants are my preferred way here, so I can change the constant in one place (in the window) when I change columns.

But you might want to let the user reorder columns.

Use localized constants for column headings. Then do

select case me.Heading(column) case kCustomer ... case kDate ... case kAmount ... etc.

OK, truth be told, I don’t use Headings either. I have a ColumnName array that I maintain in code. Heading seemed like a reasonable shortcut for those who a) don’t localize their apps and b) don’t want to build a subclass. But you’re all correct, Heading() is not the best way to go. (But it’s still better than column numbers.)

I like Eli answer: use ColumnTag.

I don’t get that. Why should localization matter when your header can use localized constants???

Who will create a testing project ?

I don’t like to waste time comparing localized constants when I can go with Constants for the indexes.

That will not work if you implement drag reordering of columns. Something to keep in mind.

Is this possible with Xojo ?
(real question: how can I do that ?)

[quote=248518:@Emile Schwarz]Is this possible with Xojo ?
(real question: how can I do that ?)[/quote]

The listbox does not support that directly, but should be able to be made to do it with some work. In the end your code would have to move the data between cells (Assuming you stored all the data in the listbox cells). The biggest problems would be how to handle the UI. Also It might be slow if there is a lot of data to move.

That said, once the UI was worked out, a data on demand type listbox or one where all the data for a row is stored in a the row tag. could be designed to make the actual data movement unnecessary. To make it transparent you would have to override many of the listbox methods.

I considered adding it to my listbox subclass, but doing it with merged cells was not practical.

  • Karen

Thank You Karen.

OK. Something like InsertColumn or DeleteColumn: not available in Xojo, but one can create it by code.

The thing I was not understanding was the Drag a Column Header part.

I have not dragged columns but I have handled drag reordering rows on my own using a picture of the row I drew. In principle it would be similar for dragging columns.

I assume you would use the MouseDrag event and draw a translucent picture of the column and assign it to the drag item. There are a lot more details of course.

  • Karen

I’ve been working with Christian’s NSTableViewMBS lately, and while the complexity of the control is frightening at first, it’s a real pleasure having listboxes that fill from a database automatically in high-speed and use a real elastic scrollbar. Apple (and Christian) are using identifiers for the columns (which are independent classes) that are different from their title. A columnWithIdentifier method helps to find them by their name.

I think the best standard place to put this identifier into is the columnTag. If you don’t use it otherwise, that is.
And if you do use it already, Xojo uses a variant so you could theoretically put a dictionary or class instance into it holding as much information as desired.

And, btw: For a Mac project, I can only recommend to take the burden of digging into TableViews. Automatic save of column widths and field order(!) included – live reorder too. That comfort outweighs the learning effort easily.

@Ulrich: very interesting. I’ve looked into the NSTableViewMBS a while ago and it looked rather incomplete. I remember that drag events were missing for instance. Frightening is a good word for this jumble of classes. Stuff like that always makes me glad to use Xojo and not Objective C.

Would you care to share your solution?

@Beatrix: Thanks a lot for the inspiration, Beatrix! Together with the idea that Xojo is working on better iOS controls where a more complex table is high on the wish list and UITableView shares many features with NSTableView, this is a really good topic for an article. Yes, I’ll do.
And, btw., I wouldn’t be surprised if the TableView was fairly complete at the time you were looking at it. It does look incomplete, compared to a listbox. By itself it doesn’t know how to query its content. The tableviews are a bit like you became bored of your family vehicle and ordered a sports car, but it arrives in parts. With great power comes great responsibility - to construct your own engine, in a way. ;( But once you did, it’s a lot of fun.

EDIT: A small appetizer: https://dl.dropboxusercontent.com/u/21200221/Xojo/NSTableView.mp4
That‘s a tableview reading ~600 entries from SQLite, with custom images in one column. I think the scrolling and refreshing speeds are amazing. You can show and hide one column via click. The tooltip-like display of text too long to fit in a cell is an automatic feature too. And finally I add a reminder and have only that row redraw.