Programming Gambas from Zip/ContextualMenus
Making Contextual Menus at Design Time
editThere is another way to create a contextual menu for when you right-click the tableview: not in code as we have done, but at design time. You still have to write code to handle the menu item clicks, but you avoid all those New Menuitem statements like mn = New Menu(Me) and su = New Menu(mn) As "MenuCopyTable". Simply use the Menu Editor to create a new menu with all its menu items. This menu will appear on the menubar, so to avoid that happening make it invisible (see the Visible checkbox below).
This is an easier way to make a contextual menu. It works if you know what the menu is going to be before you start the application. If you need to make a menu depending on what is typed in, you have to create the menu in code and use the New operator.
Sorting a GridView or TableView
editThere is no built-in sorting. I wish there were a method attached to each TableView like TableView_Sort(Column, Direction, NumericOrNot), but there isn’t. There is a good way to sort in the online wiki, here, but alas, it doesn’t sort correctly for columns containing numbers. 10 comes before 2, for example, because “1” is would come before “2” in a dictionary. The string “10” is less than the string “2” even though the number ten is greater than the number two.
(Thanks to fgores, Lee Davidson and Gianluigi of the forum for this method.)
So here is my method—somewhat agricultural, but it works. The idea is to go through the tableview row by row, gathering the cells in that row into a string with a separator between each, and putting the item that will determine the sorting right at the start of each. Sort the array, then unpack each row back into the tableview. In other words, pack each row into a string, sort the strings, and unpack each row. Use any rare and unusual character to separate the fields. Here a tilde (~) is used.
Public Sub tv1_ColumnClick(Column As Integer)
tv1.Save 'Calls the Save event in case the user clicked col heading without pressing Enter
SortTable(tv1, Column, tv1.Columns.Ascending, (Column = 1))
End
Public Sub SortTable(TheTable As TableView, Column As Integer, Ascending As Boolean, Numeric As Boolean)
Dim z As New String[]
Dim y As New String[]
Dim s As String
Dim i, j As Integer
For i = 0 To TheTable.Rows.Max
If Numeric Then
s = TheTable[i, Column].text 'next line pads it with leading zeros
s = String$(5 - Len(s), "0") 'So 23 becomes 00023, for example. Works up to 99999
Else
s = TheTable[i, Column].text
Endif
For j = 0 To TheTable.Columns.Max
s &= "~" & TheTable[i, j].text
Next
z.add(s)
Next
If Ascending Then z.Sort(gb.Ascent) Else z.Sort(gb.Descent) 'sort
For i = 0 To z.Max 'unpack the array
y = Split(z[i], "~")
For j = 1 To y.Max 'skip the first item, which is the sort key
TheTable[i, j - 1].text = y[j] 'but fill the first column
Next
Next
End