B4A Library [Class] TableView - Supports tables of any size

An improved version of this class is available here: http://www.b4x.com/forum/additional...icial-updates/30649-class-flexible-table.html


The Table class allows you to show tables of any sizes. The views (labels) are reused to avoid creating many views.

With the help of StringUtils the table can be loaded and saved to a CSV file. It shouldn't be difficult to show SQL tables using DBUtils.ExecuteMemoryTable.

SS-2012-07-04_10.38.01.png


Follow the attached example to see how the class is used. To add it to your own project you need to add the class module to your project and add a reference to StringUtils library.

RemoveRow code is available here: http://www.b4x.com/forum/showpost.php?p=146795&postcount=147

V1.10 uploaded. New method: SetColumnsWidths. Allows you to manually set the width of each column
V1.11 uploaded. Fixes a bug with grey stripes appearing.
 

Attachments

  • Table.zip
    14.9 KB · Views: 7,945
Last edited:

fsj

Member
Licensed User
Longtime User
remove row

Hello

how can I remove a complete row in the tableview?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can use this code (add it to the Table class):
B4X:
Public Sub RemoveRow(Row As Int)
   SV_ScrollChanged(SV.ScrollPosition)
   Dim sr As Int = SelectedRow
   SelectRow(-1)
   Data.RemoveAt(Row)
   If Data.Size = 0 Then
      ClearAll
      Return
   End If
   For i = minVisibleRow To maxVisibleRow
      HideRow(i)
   Next
   maxVisibleRow = Min(maxVisibleRow, Data.Size - 1)
   minVisibleRow = Min(minVisibleRow, Data.Size - 1)
   For i = minVisibleRow To maxVisibleRow
      ShowRow(i)
   Next
   If sr = Row Then
      sr = -1
   Else If sr > Row Then
      sr = sr - 1
   End If
   SelectRow(sr)
   SV.Panel.Height = Data.Size * RowHeight
   SV_ScrollChanged(Min(SV.ScrollPosition, SV.Panel.Height))
End Sub
 

Smee

Well-Known Member
Licensed User
Longtime User
Tab Delimiting

I am trying to use the excellent V1.11_2d of this program. However i am using a TAB delimited file because the fields of the file contain commas. is there a way to do this?
 

BasicBert

Member
Licensed User
Longtime User
I am trying to use the excellent V1.11_2d of this program. However i am using a TAB delimited file because the fields of the file contain commas. is there a way to do this?

In the Table class routines that load and save the csv file you can change the "," into the separator you wish. Here are the lines that are of interest :

B4X:
List1 = StringUtils1.LoadCSV2(Dir, Filename, ",", headers)
B4X:
List1 = StringUtils1.LoadCSV(Dir, Filename, ",")
B4X:
StringUtils1.SaveCSV2(Dir, Filename, ",", Data, headers)

If you put the code for the Tab character here, you should be fine.

I see I'm using a later version of the table class (Klaus's 1_13_2D), but the used code is from the StringUtils Lib and should be the same.

Succes.
 

Smee

Well-Known Member
Licensed User
Longtime User
Thanks for the reply,

However i do not really want to modify the class code routines because i like to keep the code the same for all modules. I am working on a fix. will post if i have any luck
 

melamoud

Active Member
Licensed User
Longtime User
adding functunality to the excelent table class

hi,

i'm using the table class, and needed more funcunality like multi select , singleLine cell, hide columns, etc ,
I added the desired code, and wants to share it with all, is this the right place ?

it is based on the updated code from Klaus at http://www.b4x.com/forum/111926-post22.html

here is the updated code:
B4X:
'Version 1.14

' Whats new 1.14
' alignement now is set in the Initialize sub
' added removeRow() sub to remove a specifc row from the table - this is EREL's removeRow adopted to 1.13 and to the rest of the changes in 1.14
' added getValues() sub to get the entire row in an array, thought this is usefull
' added updateRow() sub to set an entire row at once, Vs cell by cell, in tables many times, developer work by rows , update an entire row
' added ability to set (and get) the lables to be singleLine or multiLine lables (deafult is singleLine) this feature depend on reflection lib - setting this attribute will clear the table!!!
' added getHeaderPanel sub to return he header panel so developer can get access to the header components , for example to show tooltip, or quickAction on the header location 
' added ability to turn on and off multi selection of rows, User can now select one row or any number of rows, developer can use that functunality to , for example change status of many rows at once, or remove many rows with one user action
' added getSelectedRows to return list of selected rows
' added ability to hide/unhide a specific column, so it will be part of the table but hidden from the user, this is usefull to if developer wants to maintain additional data in the table (this is not a complete data model / view model implementation)


' with ScrollView2 instead of ScrollView
' with highlighting of the selected cell

Sub Class_Globals
   Private StringUtils1 As StringUtils
   Private SV As ScrollView2D
   Private Header As Panel
   Private Callback As Object
   Private Event As String
   'Private SelectedRow As Int
   Private SelectedRows As List ' selected rows
   Private SelectedCol As Int ' ???
   Private Data As List
   Private LabelsCache As List
   Private minVisibleRow, maxVisibleRow As Int
   Private visible As Boolean
   Public visibleRows As Map
   Private NumberOfColumns, ColumnWidth As Int
   Public RowHeight, HeaderColor, TableColor, FontColor, HeaderFontColor As Int
   Public FontSize As Float
   Type RowCol (Row As Int, Col As Int)
   Public Alignment As Int
   Public SelectedDrawable(), Drawable1(), Drawable2() As Object
   Public SelectedCellDrawable As Object
   'Table settings
   HeaderColor = Colors.Gray
   RowHeight = 30dip
   TableColor = Colors.LightGray
   FontColor = Colors.Black
   HeaderFontColor = Colors.White
   FontSize = 14
   Alignment = Gravity.CENTER 'change to Gravity.LEFT or Gravity.RIGHT for other alignments.
   
   Public singleLine As Boolean = True ' does a lable hold a single line text or multiline , need to be set rigth after call to initialize 
   Private multiSelect As Boolean = False
   Private SavedWidths() As Int' to keep the user set widths for columns 
End Sub

' nir adding alignment as parameter to initialize
Public Sub Initialize (CallbackModule As Object, EventName As String, vNumberOfColumns As Int, cellAlignement As Int)
   SV.Initialize(0, 0, "SV")
   SelectedRows.Initialize
   Alignment = cellAlignement
   SV.Panel.Color = TableColor
   Callback = CallbackModule
   Event = EventName
   innerClearAll(vNumberOfColumns)
End Sub

'Clears the table
Public Sub ClearAll
   innerClearAll(NumberOfColumns)
End Sub


'Sets the columns widths.
'Example: <code>Table1.SetColumnsWidths(Array As Int(100dip, 30dip, 30dip, 100%x - 160dip))</code>
Public Sub SetColumnsWidths(Widths() As Int)
   ' clone (keep) Widths
   Dim SavedWidths(Widths.Length) As Int
   For i=0 To Widths.Length-1
      SavedWidths(i) = Widths(i) 
   Next
   
   Dim v As View
   For i = 0 To Widths.Length - 1
      v = Header.GetView(i)
      v.Width = Widths(i) - 1dip
      If i > 0 Then
         v.Left = Header.GetView(i-1).Left + Widths(i-1) + 1dip
      End If
   Next
   Header.Width = Header.GetView(Widths.Length - 1).Left + Widths(Widths.Length - 1)
   SV.Panel.Width = Header.Width
   Dim lbls() As Label
   For i = 0 To visibleRows.Size - 1
      lbls = visibleRows.GetValueAt(i)
      For lbl = 0 To lbls.Length - 1
         lbls(lbl).SetLayout(Header.GetView(lbl).Left, lbls(lbl).Top, _
            Header.GetView(lbl).Width, RowHeight)
      Next
   Next
End Sub

Private Sub innerClearAll(vNumberOfColumns As Int)
   SelectedRows.Initialize
   For i = SV.Panel.NumberOfViews -1 To 0 Step -1
      SV.Panel.RemoveViewAt(i)
   Next
   NumberOfColumns = vNumberOfColumns
   Dim Drawable1(NumberOfColumns) As Object
   Dim Drawable2(NumberOfColumns) As Object
   Dim SelectedDrawable(NumberOfColumns) As Object
   For i = 0 To NumberOfColumns - 1
      Dim cd1, cd2, cd3 As ColorDrawable
      cd1.Initialize(Colors.White, 0)
      cd2.Initialize(0xFF98F5FF, 0)
      cd3.Initialize(0xFF007FFF, 0)
      Drawable1(i) = cd1
      Drawable2(i) = cd2
      SelectedDrawable(i) = cd3
   Next
   Dim cd4 As ColorDrawable
   cd4.Initialize(0xFFFC8EAC, 0)
   SelectedCellDrawable = cd4
   
   SV.Panel.Height = 0
   'SelectedRow = -1
   SelectedCol = -1
   minVisibleRow = -1
   maxVisibleRow = 0
   Data.Initialize
   LabelsCache.Initialize
   visibleRows.Initialize
   SV.VerticalScrollPosition = 0
   DoEvents
   SV.VerticalScrollPosition = 0
   For i = 1 To 80 'fill the cache to avoid delay on the first touch
      LabelsCache.Add(CreateNewLabels)
   Next
   If visible Then
      SV_ScrollChanged(0, 0)
   End If
End Sub

Private Sub SV_ScrollChanged(PosX As Int, PosY As Int)
   Dim currentMin, currentMax As Int
   currentMin = Max(0, PosY / RowHeight - 30)
   currentMax = Min(Data.Size - 1, (PosY + SV.Height) / RowHeight + 30)
   If minVisibleRow > -1 Then
      If minVisibleRow < currentMin Then
         'need to hide the upper rows
         For I = minVisibleRow To Min(currentMin - 1, maxVisibleRow)
            HideRow(I)
         Next
      Else If minVisibleRow > currentMin Then
         'need to show the upper rows
         For I = currentMin To Min(minVisibleRow - 1, currentMax)
            ShowRow(I)
         Next
      End If
      If maxVisibleRow > currentMax Then
         'need to hide the lower rows
         For I = maxVisibleRow To Max(currentMax + 1, minVisibleRow) Step -1
            HideRow(I)
         Next
      Else If maxVisibleRow < currentMax Then
         'need to show the lower rows
         For I = currentMax To Max(maxVisibleRow + 1, currentMin) Step -1
            ShowRow(I)
         Next
      End If
   End If
   minVisibleRow = currentMin
   maxVisibleRow = currentMax
   Header.Left = -PosX

End Sub

'Adds the tablet to the activity.
Public Sub AddToActivity(Act As Activity, Left As Int, Top As Int, Width As Int, Height As Int)
   visible = True
   Header.Initialize("")
   Header.Color = TableColor
   Act.AddView(Header, Left, Top , Width, RowHeight)
   Act.AddView(SV, Left, Top + RowHeight, Width, Height - RowHeight)
   ColumnWidth = SV.Width / NumberOfColumns
   
   SV_ScrollChanged(0, 0)

End Sub

'Adds a row to the table
'Example:<code>Table1.AddRow(Array As String("aaa", "ccc", "ddd", "eee"))</code>
Public Sub AddRow(Values() As String)
   If Values.Length <> NumberOfColumns Then
      Log("Wrong number of values =" & Values.Length & " col=" & NumberOfColumns)
      Return
   End If
   Data.Add(Values)
   Dim lastRow As Int
   lastRow = Data.Size - 1
   If lastRow < (SV.VerticalScrollPosition + SV.Height) / RowHeight + 1 Then
      ShowRow(lastRow)      
   End If
   SV.Panel.Height = Data.Size * RowHeight
End Sub

Private Sub ShowRow(row As Int)
   If visibleRows.ContainsKey(row) Then Return
   'Log("ShowRow: " & row)
   Dim lbls() As Label
   Dim values() As String
   lbls = GetLabels(row)
   values = Data.get(row)
   visibleRows.Put(row, lbls)
   Dim rowColor() As Object
   If (SelectedRows.indexof(row) <> -1 )Then
      rowColor = SelectedDrawable
   Else If row Mod 2 = 0 Then
      rowColor = Drawable1
   Else
      rowColor = Drawable2
   End If
   For I = 0 To lbls.Length - 1
      SV.Panel.AddView(lbls(I), Header.GetView(I).Left, row * RowHeight, Header.GetView(I).Width, _
         RowHeight - 1dip)
      lbls(I).Text = values(I)
      If I = SelectedCol AND (SelectedRows.indexof(row) <> -1) Then
         lbls(I).Background = SelectedCellDrawable
      Else
         lbls(I).Background = rowColor(I)
      End If
   Next
End Sub

Private Sub IsRowVisible(Row As Int) As Boolean
   Return Row < (SV.VerticalScrollPosition + SV.Height) / (RowHeight + 1) AND _
      Row > SV.VerticalScrollPosition / RowHeight
End Sub

Private Sub HideRow (Row As Int)
   'Log("HideRow: " & row)
   Dim lbls() As Label
   lbls = visibleRows.get(Row)
   If lbls = Null Then 
      Log("HideRow: (null) " & Row)
      Return
   End If
   For I = 0 To lbls.Length - 1   
      lbls(I).RemoveView
   Next
   visibleRows.Remove(Row)
   LabelsCache.Add(lbls)
End Sub

Private Sub GetLabels(Row As Int) As Label()
   Dim lbls() As Label
   If LabelsCache.Size > 0 Then
      'Log("from cache")
      lbls = LabelsCache.get(LabelsCache.Size - 1)
      LabelsCache.RemoveAt(LabelsCache.Size - 1)
   Else
      lbls = CreateNewLabels      
   End If
   For I = 0 To lbls.Length - 1
      Dim rc As RowCol
      rc = lbls(I).Tag
      rc.Row = Row
   Next
   Return lbls
End Sub


Private Sub CreateNewLabels As Label()
   Dim lbls(NumberOfColumns) As Label
   For I = 0 To NumberOfColumns - 1
      Dim rc As RowCol
      rc.Col = I
      Dim l As Label
      l.Initialize("cell")
      l.Gravity = Alignment
      l.TextSize = FontSize
      l.TextColor = FontColor
      ' added by nir, make each label single line
      If (singleLine) Then 
         Dim ref As Reflector
         ref.Target = l
         ref.RunMethod2("setSingleLine", True, "java.lang.boolean")
      End If
      l.Tag = rc
      lbls(I) = l
   Next
   Return lbls
End Sub
'Set the headers values
'Example:<code>Table1.SetHeader(Array As String("Col1", "Col2", "Col3"))</code>
Public Sub SetHeader(Values() As String)
   For I = Header.NumberOfViews - 1 To 0 Step -1
      Header.RemoveViewAt(I)
   Next
   For I = 0 To NumberOfColumns - 1
      Dim l As Label
      l.Initialize("header")
      l.Gravity = Gravity.CENTER
      l.TextSize = FontSize
      l.Color = HeaderColor
      l.TextColor = HeaderFontColor
      l.Text = Values(I)
      l.Tag = I
      Header.AddView(l, ColumnWidth * I, 0, ColumnWidth - 1dip, RowHeight)
   Next
End Sub

Private Sub Cell_Click
   Dim rc As RowCol
   Dim l As Label
   l = Sender
   rc = l.Tag
'   SelectRow(rc.Row)
   SelectRow(rc)
   If SubExists(Callback, Event & "_CellClick") Then
      CallSub3(Callback, Event & "_CellClick", rc.Col, rc.Row)
   End If
End Sub

Private Sub Header_Click
   Dim l As Label
   Dim col As Int
   l = Sender
   col = l.Tag
   If SubExists(Callback, Event & "_HeaderClick") Then
      CallSub2(Callback, Event & "_HeaderClick", col)
   End If
End Sub

'Gets the value of the given cell.
Public Sub GetValue(Col As Int, Row As Int)
   Dim values() As String
   values = Data.get(Row)
   Return values(Col)
End Sub
'Sets the value of the given cell.
Public Sub SetValue(Col As Int, Row As Int, Value As String)
   Dim values() As String
   values = Data.get(Row)
   values(Col) = Value
   If visibleRows.ContainsKey(Row) Then
      Dim lbls() As Label
      lbls = visibleRows.get(Row)
      lbls(Col).Text = Value
   End If
End Sub


Private Sub SelectRow(rc As RowCol)
   Dim prevIndex As Int
   Dim prev As Int ' if we select an alreday selected row, prev will be rc.row, else will be -1
   prevIndex = SelectedRows.indexof(rc.Row)    ' -1 if selecting not a selected row   
   If (prevIndex <> -1 AND (multiSelect = False)) Then
      ' do nothing we select row that is selected already
      Return
   End If
   
   If (prevIndex = -1) Then
      If (multiSelect) Then 
         SelectedRows.add(rc.Row) 'Select the new row
         prev = -1
      Else ' set selected to the new one
         ' hide / show all selected rows      
         'Log ("get at zero: " & SelectedRows)
         If (SelectedRows.Size <> 0) Then 
            prev = SelectedRows.get(0) ' there should be only one here ever!!!, keep the unselected row in prev
            SelectedRows.set(0,rc.Row) ' change it to the new one
         Else 
            prev = -1
            SelectedRows.Add(rc.Row)
         End If
      End If
   Else ' multi select and found a row (unselect it)
      'Log ("multi select and found row")
      prev = SelectedRows.get(prevIndex) ' should be RC.row
      SelectedRows.RemoveAt(prevIndex) ' deselect the old selected row      
   End If
   'remove the color of previously selected row
   If prev > -1 Then
      If visibleRows.ContainsKey(rc.Row) Then
         HideRow(prev)
         ShowRow(prev)
      End If
   End If
   
   SelectedCol = rc.col
   'For col = 0 To NumberOfColumns - 1
      If visibleRows.ContainsKey(rc.Row) Then
         HideRow(rc.Row)
         ShowRow(rc.Row)
      End If
   'Next
End Sub

'Makes the given row visible.
Public Sub JumpToRow(Row As Int)
   SV.VerticalScrollPosition = Row * RowHeight
End Sub

'Clears the previous table and loads the CSV file to the table.
'You should first add the Table to the activity before calling this method.
Public Sub LoadTableFromCSV(Dir As String, Filename As String, HeadersExist As Boolean)
   
   Dim List1 As List
   Dim h() As String
   If HeadersExist Then
      Dim headers As List
      List1 = StringUtils1.LoadCSV2(Dir, Filename, ",", headers)
      Dim h(headers.Size) As String
      For i = 0 To headers.Size - 1
         h(i) = headers.get(i)
      Next
   Else
      List1 = StringUtils1.LoadCSV(Dir, Filename, ",")
      Dim firstRow() As String
      firstRow = List1.get(0)
      Dim h(firstRow.Length)
      For i = 0 To firstRow.Length - 1
         h(i) = "Col" & (i + 1)
      Next
   End If
   innerClearAll(h.Length)
   ColumnWidth = SV.Width / NumberOfColumns
   SetHeader(h)
   For i = 0 To List1.Size - 1
      Dim row() As String
      row = List1.get(i)
      AddRow(row)
   Next
End Sub

'Saves the table to a CSV file.
Public Sub SaveTableToCSV(Dir As String, Filename As String)
   Dim headers(NumberOfColumns) As String
   For i = 0 To headers.Length - 1
      Dim l As Label
      l = Header.GetView(i)
      headers(i) = l.Text
   Next
   StringUtils1.SaveCSV2(Dir, Filename, ",", Data, headers)
End Sub

' --------------------------------------------------------------------------------------------------------
' new functunality added by nir -->


' remove a row
'row is the row number
Public Sub RemoveRow(Row As Int)   
   If (Row <0 OR row > Data.Size-1) Then Return ' cant remove row outside of the table scope
    SV_ScrollChanged(SV.HorizontalScrollPosition,SV.VerticalScrollPosition)
    Dim sr As Int ' to keep the previos selected row (in case multiSelect is off)
   'sr = -1 ' not the selected row
   
   Dim prevIndex As Int 
   prevIndex = SelectedRows.IndexOf(Row) ' if the rmeoved one was selected or not/
   
   For i=0 To SelectedRows.Size -1 ' updated selection
      Dim keepSel As Int
      keepSel = SelectedRows.get(i)
      If (keepSel > Row) Then          
         SelectedRows.Set(i,keepSel-1) ' dec row number in all rows appear after the soon tobe removed removed row
         ' future optimization: hide and show all rows touched and that within visible range, for now we hide/show all rows in visible scope
      End If
   Next 
   
   If (prevIndex <> -1) Then 
      'sr = Row ' in case the row was selected keep it in sr
      SelectedRows.RemoveAt(prevIndex) ' removed the current row from the selected list
   End If
   
   Dim cr As RowCol
   
   Data.RemoveAt(Row)
    For i = minVisibleRow To maxVisibleRow ' hide all visible rows
        HideRow(i)
    Next

   'If multiSelect = False Then
   '   If sr = Row Then ' current selected row was deleted
   '        sr = -1
   '    Else If sr > Row Then
   '        sr = sr - 1
   '   End If
    'End If

   maxVisibleRow = Min(maxVisibleRow, Data.Size - 1) ' adjust visible rows
    minVisibleRow = Min(minVisibleRow, Data.Size - 1)
    For i = minVisibleRow To maxVisibleRow ' show all visible rows (should select the ones needed to be selected as well)
      'If (multiSelect OR sr = i) Then HideRow(i) ' in multi select we made too much mess, we need to redraw the whole view (can be optimized if needed!)
        ShowRow(i)
    Next
   
    SV.Panel.Height = Data.Size * RowHeight
    SV_ScrollChanged(SV.HorizontalScrollPosition,Min(SV.VerticalScrollPosition, SV.Panel.Height))
End Sub


' return array of strings hold all the values for a row.
Public Sub getValues(Row As Int ) As String()
   Dim rowData() As String  = data.Get(row) ' will throw an excpetion if row is not correct
   Dim tmp(NumberOfColumns) As String
   For i=0 To NumberOfColumns-1 ' copy the array
      tmp(i) =  rowData(i)
   Next
   Return tmp
End Sub


' update a row in the table
' row is the row number to update, Values is an array of string at the size of the number of columns
' return true is worked out, false if failed
Public Sub UpdateRow(Row As Int, Values () As String) As Boolean
   Dim i As Int
   If (Values.Length <> NumberOfColumns OR Row <0 OR Row>Data.Size-1) Then
      Return False
   End If
   For i=0 To Values.Length-1
      SetValue(i,Row,Values(i))
   Next
   Return True
End Sub

' set multi select flag, and clear the selected list (just in case)
' when multiSelect is true, click on a not selected row will add that row to the selected list of rows, and click on an selected row will unselect it
' when multiSelect is false, click on a row will select it (or reselect it if alreday selected)
Sub setMultiSelect(ms As Boolean)
   SelectedRows.Clear
   multiSelect = ms
End Sub

' return true is the table us set to multi select 
Sub getMultiSelect As Boolean 
   Return multiSelect
End Sub

' return the header panel
Sub getHeaderPanel As Panel
   Return Header
End Sub

' return the selected rows number as a list of int.
Sub getSelectedRows As List
   Dim sr As List
   sr.Initialize
   sr.AddAll(SelectedRows)
   Return sr
End Sub


' set column col to length '1' which mean it willbe hidden
Sub hideCol(col As Int) 
   Dim tmpWidths(SavedWidths.Length) As Int
   For i=0 To SavedWidths.Length-1
      tmpWidths(i) = SavedWidths(i) 
   Next
   tmpWidths(col) = 1
   SetColumnsWidths(tmpWidths)   
End Sub

' unhide column col, and give it a new size
Sub unHideCol(col As Int, newSize As Int) 
   Dim tmpWidths(SavedWidths.Length) As Int
   For i=0 To SavedWidths.Length-1
      tmpWidths(i) = SavedWidths(i) 
   Next
   tmpWidths(col) = newSize
   SetColumnsWidths(tmpWidths)
End Sub
 

Smee

Well-Known Member
Licensed User
Longtime User
Great additions. Thank you

Is there a way to insert the row at the beginning instead of at the end?

i tried this code by Helen but it does not work

B4X:
Public Sub InsertRow(Values() As String)
    If Values.Length <> NumberOfColumns Then
        Log("Wrong number of values.")
        Return
    End If
    Data.InsertAt(0, Values)

    Dim lastRow As Int
    Dim lr As RowCol
   
   lastRow = Data.Size - 1
    For i = lastRow To 0 Step -1
        If lastRow < (SV.VerticalScrollPosition + SV.Height) / RowHeight + 1 Then
            ShowRow(lastRow)        
        End If
      
       SelectRow(lastRow)

        SV.Panel.Height = Data.Size * RowHeight
        lastRow = lastRow -1
    Next
    
End Sub

i get a type error on this line
SelectRow(lastRow)

it has been dim as int instead of rowcol and throws an error. no matter what i try i cannot get it to work
 
Last edited:

melamoud

Active Member
Licensed User
Longtime User
Here it is

B4X:
Public Sub insertRowAt (row As Int, Values() As String)
   If (row < 0) Then row = 0
   If (row > Data.Size) Then 
      AddRow(Values)
      Return True      
   End If
    SV_ScrollChanged(SV.HorizontalScrollPosition,SV.VerticalScrollPosition) ' this strange call will set min/max visible area

   Dim l As List
   l.Initialize
   l.Add(Values)
   ' fix selection
   For i=0 To SelectedRows.Size -1 ' updated selection
      Dim keepSel As Int
      keepSel = SelectedRows.get(i)
      If (keepSel >= row) Then          
         SelectedRows.Set(i,keepSel+1) ' dec row number in all rows appear after the soon tobe removed removed row
         ' future optimization: hide and show all rows touched and that within visible range, for now we hide/show all rows in visible scope
      End If
   Next 
   For i = minVisibleRow To maxVisibleRow 
      HideRow(i)
   Next
   Data.AddAllAt(row,l) ' now I can add the row
   
    SV_ScrollChanged(SV.HorizontalScrollPosition,SV.VerticalScrollPosition) ' this strange call will set min/max visible area   

   For i = minVisibleRow To maxVisibleRow 
      ShowRow(i)
   Next
   
    SV.Panel.Height = Data.Size * RowHeight
    SV_ScrollChanged(SV.HorizontalScrollPosition,Min(SV.VerticalScrollPosition, SV.Panel.Height))   
End Sub
 

Smee

Well-Known Member
Licensed User
Longtime User
That works great, thankyou.
i have a problem with the row dividers. Some look ok, others look like ellipsis others look like strange characters

any ideas why? i have a posted a screenshot
 

Attachments

  • Screenshot_2013-01-23-20-39-51.jpg
    Screenshot_2013-01-23-20-39-51.jpg
    34.4 KB · Views: 486
Last edited:

Smee

Well-Known Member
Licensed User
Longtime User
yes i did. it also does it when i set it to 1
 
Top