B4J Question "Funny" Checkbox 😠

LucaMs

Expert
Licensed User
Longtime User
B4J_RxfwDuYezc.gif



Its state in the Sub UpdateDialog is always fixed, the one set in the Designer.


I can solve it with a workaround, I can pass the state to the Sub UpdateDialog (the stateS, since they are multiple checkboxes) but if I could figure out the reason for this behavior it would be much better.


Certainly important note: chkShowPositive is in an item of a CustomListView.
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
I can solve it with a workaround, I can pass the state to the Sub UpdateDialog (the stateS, since they are multiple checkboxes) but if I could figure out the reason for this behavior it would be much better.
I could come up with another alternative: pass the B4XView that "invoked" UpdateDialog to UpdateDialog, get the CLV item and from there all the views it contains.

But these are still "workarounds" :confused:
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I need a small project to better understand the issue.

I'll add a small example project, but I think I understand the problem and will try to explain it, so perhaps it will be useful to others as well (if things are as I'm about to write; you, @Erel, will be more precise and use more precise terms).

Example.

Suppose you create a CustomListView (CLV for short) to which you want to add N items containing only a Label and an EditText (better a B4XFloatTextField, but it's an example).
You create a function (a Sub) that returns a B4XView (Pane(L)) in which you create, or load from a file, the Label and EditText; you also set their properties within that function.
Now, although the two Views are declared at the module level and not in the function - there are no local variables in B4X - you will have N copies of those Views in the CLV, each with its properties set to different values. In the Sub-Function, you will have a "current" Label and EditText at each call.

This is definitely unusual behavior, although it works. It's not a bug; it's the way this thing works.

My mistake was trying to access a View of a CLV from within a Sub X, obviously without declaring it - the View I obtained by selecting an item from the CLV - rather than passing the View to Sub X, as if that View were the current one for the entire class.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I need a small project to better understand the issue.
I'm attaching the small B4J project, but I'm also posting the source code; it's easy to read.

(Note: Thanks to this, I've seen that a modification to the "Create CustomListView items" snippet would be useful, as it would also have a placeholder for the layout file :) )

B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI

    Private clvTest As CustomListView
    Private btnTest As B4XView
    Private lblTest As B4XView
    Private lblButtonText As B4XView
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    
    FillCLV
End Sub

Private Sub FillCLV
    clvTest.Clear
    For i = 0 To 9
        Dim Text As String = "# " & i
        clvTest.Add(CreateCLVItem(Text), i)
    Next
End Sub

Private Sub CreateCLVItem(Text As String) As B4XView
    Dim pnlItem As B4XView = xui.CreatePanel("")
    pnlItem.SetLayoutAnimated(0, 0, 0, clvTest.GetBase.Width, 50dip)
    pnlItem.LoadLayout("layCLV_Item")

    lblTest.Text = Text
    btnTest.Text = "button " & Text
    Return pnlItem
End Sub

Private Sub btnTest_Click
'    Dim btn As B4XView = Sender
    Test
End Sub

Private Sub Test
    'Here btnTest is NOT the one clicked.
    'To work correctly, i should pass the btn in btnTest_Click to this Sub.
    lblButtonText.Text = btnTest.Text
End Sub
 

Attachments

  • CLV_Test.zip
    3.6 KB · Views: 5
Upvote 0

teddybear

Well-Known Member
Licensed User
The problem is certainly related to the strange behavior of CustomListViews.

You declare a pair of Views in Class_Globals, therefore at the class level, but when you fill a CustomListView with items, loading those two Views from a layout, it's as if they become local (and multiple) variables.
That's fine. the views you declare in Class_Globals are just references, not local variables.
They will be initialized during loadLayout, and the views will reference the last loadLayout.
All events for the btntest view refer to btnTest_click; you must use sender to pass the object for sub.
 
Upvote 0

fernando1987

Active Member
Licensed User
That's fine. the views you declare in Class_Globals are just references, not local variables.
They will be initialized during loadLayout, and the views will reference the last loadLayout.
All events for the btntest view refer to btnTest_click; you must use sender to pass the object for sub.
B4X:
Private Sub btnTest_Click
    
    Dim btn As B4XView = Sender
    btnTest =    btn
    Test
End Sub

Private Sub Test
    'Here btnTest is NOT the one clicked.
    'To work correctly, i should pass the btn in btnTest_Click to this Sub.
    lblButtonText.Text = btnTest.Text
End Sub
I'm a little confused but I don't know if this is what is expected.
 
Upvote 0

teddybear

Well-Known Member
Licensed User
B4X:
Private Sub btnTest_Click
   
    Dim btn As B4XView = Sender
    btnTest =    btn
    Test
End Sub

Private Sub Test
    'Here btnTest is NOT the one clicked.
    'To work correctly, i should pass the btn in btnTest_Click to this Sub.
    lblButtonText.Text = btnTest.Text
End Sub
I'm a little confused but I don't know if this is what is expected.
This is correct.
 
Upvote 0
Top