Programming Gambas from Zip/ContextualMenus

Making Contextual Menus at Design TimeEdit

There 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 TableViewEdit

There 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))

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
        s = TheTable[i, Column].text
    For j = 0 To TheTable.Columns.Max
      s &= "~" & TheTable[i, j].text

  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
Programming Gambas from Zip
 ← FormArranging ContextualMenus Ascii →