B4J Question B4XTable not resize when search

yiankos1

Well-Known Member
Licensed User
Longtime User
Hello team,
I user B4XTable and i use Erel's code to resize columns based on content. When i use search to find something, if a cell has been resized and corresponds to search terms, whole colum returns to previous state.
Thank you for your time.

I attach you two photos before and after search
1.jpg

2.jpg
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Test this code:
B4X:
Sub B4XTable1_DataUpdated
   Dim ShouldRefresh As Boolean
   For Each column As B4XTableColumn In Array(NameColumn)
       Dim MaxWidth As Int
       For Each id As Long In B4XTable1.VisibleRowIds
           If id = 0 Then Continue
           Dim Text As String = B4XTable1.sql1.ExecQuerySingleResult2($"SELECT ${column.SQLID} FROM data WHERE rowid = ?"$, _
               Array(id))
           MaxWidth = Max(MaxWidth, cvs.MeasureText(Text, B4XTable1.LabelsFont).Width + 10dip)
       Next
       If MaxWidth > column.ComputedWidth Or MaxWidth < column.ComputedWidth - 20dip Then
           column.Width = MaxWidth
           ShouldRefresh = True
       End If
   Next
   If ShouldRefresh Then
       B4XTable1.Refresh
   End If
End Sub
 
Upvote 0

AnandGupta

Expert
Licensed User
Longtime User
Test this code:
Erel,

I see that we have B4XTable features/solutions codes, as requested by members, given at many threads.
Can we have all of them in the B4XTable thread or a new "B4XTable Features Solution" ?
This way, I think, when we use B4XTable, we can access all the codes, as required, in one place. As Forum search for the codes is not simple, IMHO.

Regards,

Anand
 
Last edited:
Upvote 0

yiankos1

Well-Known Member
Licensed User
Longtime User
Test this code:
B4X:
Sub B4XTable1_DataUpdated
   Dim ShouldRefresh As Boolean
   For Each column As B4XTableColumn In Array(NameColumn)
       Dim MaxWidth As Int
       For Each id As Long In B4XTable1.VisibleRowIds
           If id = 0 Then Continue
           Dim Text As String = B4XTable1.sql1.ExecQuerySingleResult2($"SELECT ${column.SQLID} FROM data WHERE rowid = ?"$, _
               Array(id))
           MaxWidth = Max(MaxWidth, cvs.MeasureText(Text, B4XTable1.LabelsFont).Width + 10dip)
       Next
       If MaxWidth > column.ComputedWidth Or MaxWidth < column.ComputedWidth - 20dip Then
           column.Width = MaxWidth
           ShouldRefresh = True
       End If
   Next
   If ShouldRefresh Then
       B4XTable1.Refresh
   End If
End Sub

Extending Erel's answer, if you want to calculate header's text width, you can do it with this code:
B4X:
Dim ShouldRefresh As Boolean
    'NameColumn and NumberColumn are global B4XTableColumns that we want to measure
    For Each Column As B4XTableColumn In NameColumn
        Dim MaxWidth As Int
        For Each id As Long In tblMain.VisibleRowIds
            If id = 0 Then
                Dim pnl As B4XView = Column.CellsLayouts.Get(0)
                Dim lbl As B4XView = pnl.GetView(0)
                MaxWidth = Max(MaxWidth, cvs.MeasureText(lbl.Text, lbl.Font).Width + 10dip)
            Else
                Dim Text As String = tblMain.sql1.ExecQuerySingleResult2($"SELECT ${Column.SQLID} FROM data WHERE rowid = ?"$, _
               Array(id))
            End If
            MaxWidth = Max(MaxWidth, cvs.MeasureText(Text, tblMain.LabelsFont).Width + 10dip)
        Next
        If MaxWidth > Column.ComputedWidth Or MaxWidth < Column.ComputedWidth - 20dip Then
            Column.Width = MaxWidth
            ShouldRefresh = True
        End If
    Next
    
    If ShouldRefresh Then
        tblMain.Refresh
    End If
 
Upvote 0

yiankos1

Well-Known Member
Licensed User
Longtime User
You are making an assumption that is not always be correct.
id is 0 for empty rows. If there aren't any empty rows then it will not be 0.

You should instead move the code to calculate the header width outside of this loop and keep the 'if id =0 Then continue'.
Thank you for pointing this out
B4X:
Dim ShouldRefresh As Boolean
    'NameColumn and NumberColumn are global B4XTableColumns that we want to measure
    For Each Column As B4XTableColumn In NameColumn
        Dim MaxWidth As Int
        For Each id As Long In tblMain.VisibleRowIds
            If id = 0 Then Continue
            Dim Text As String = tblMain.sql1.ExecQuerySingleResult2($"SELECT ${Column.SQLID} FROM data WHERE rowid = ?"$, _
           Array(id))   
            MaxWidth = Max(MaxWidth, cvs.MeasureText(Text, tblMain.LabelsFont).Width + 10dip)
        Next
        
        Dim pnl As B4XView = Column.CellsLayouts.Get(0)
        Dim lbl As B4XView = pnl.GetView(0)
        MaxWidth = Max(MaxWidth, cvs.MeasureText(lbl.Text, lbl.Font).Width + 10dip)
        
        If MaxWidth > Column.ComputedWidth Or MaxWidth < Column.ComputedWidth - 20dip Then
            Column.Width = MaxWidth
            ShouldRefresh = True
        End If
    Next
    
    If ShouldRefresh Then
        tblMain.Refresh
    End If
 
Upvote 0
Top