Italian Object by expression or Indirection

Massimo66

Member
Salve devo settare le proprietà di un numero di bottoni da Butto1 a button10.
C'è un modo per farlo con un ciclo for next ?
Esiste un modo per fare riferimento ad un Button o Label ecc con un' esperssione stringa ?
in windev, usando l'indirezione posso fare: {"Button" & i}.Text="Button" & i
Grazie
 

Lello1964

Well-Known Member
Licensed User
Longtime User
B4X:
Sub Globals

  Dim buttons(13) as button

end sub

Sub Activity_Create(FirstTime as Boolean)
  for i = 0 to 13 -1
    buttons(i).Initialize("buttons")
    buttons(i).tag = i
  next
end sub


Sub buttons_click
  dim b as button = sender
  bid = b.tag
  if bid=0 then
    buttons(3).enable=false

    buttons(5).enable=false
  endif

end sub
 

Lello1964

Well-Known Member
Licensed User
Longtime User
oppure :

B4X:
For Each btn As Button In Array(Button1, Button2, Button3)
         btn.Enabled = b
         If b Then btn.Text = "enabled" Else btn.Text = "disable"
Next
 

Sagenut

Expert
Licensed User
Longtime User
La soluzione di @Lello1964 và bene se i Button vengono creati da codice (cosa che è meglio evitare nel 90% dei casi).
Se i Button sono stati aggiunti nel Layout tramite Designer allora puoi provare così
B4X:
Dim count As Int = 1
For Each v As View In Activity.GetAllViewsRecursive
    If v Is Button Then
        v.As(Button).Text = "Button " & count
        count = count + 1
    End If
Next
NOTA BENE: quì faccio riferimento ad un progetto DEFAULT che utilizza le Activity. Dovresti evitarlo fin da subito e passare immediatamente alle B4XPages.
Trovi un video che le introduce quì (oltre a tanti esempi sul forum)
https://www.b4x.com/etp.html?vimeography_gallery=1&vimeography_video=440642051
In quel caso dovresti solo cambiare ACTIVITY con ROOT
B4X:
Dim count As Int = 1
For Each v As View In Root.GetAllViewsRecursive
    If v Is Button Then
        v.As(Button).Text = "Button " & count
        count = count + 1
    End If
Next
 

Lello1964

Well-Known Member
Licensed User
Longtime User
La soluzione di @Lello1964 và bene se i Button vengono creati da codice (cosa che è meglio evitare nel 90% dei casi).
Se i Button sono stati aggiunti nel Layout tramite Designer allora puoi provare così
B4X:
Dim count As Int = 1
For Each v As View In Activity.GetAllViewsRecursive
    If v Is Button Then
        v.As(Button).Text = "Button " & count
        count = count + 1
    End If
Next
NOTA BENE: quì faccio riferimento ad un progetto DEFAULT che utilizza le Activity. Dovresti evitarlo fin da subito e passare immediatamente alle B4XPages.
Trovi un video che le introduce quì (oltre a tanti esempi sul forum)
https://www.b4x.com/etp.html?vimeography_gallery=1&vimeography_video=440642051
In quel caso dovresti solo cambiare ACTIVITY con ROOT
B4X:
Dim count As Int = 1
For Each v As View In Root.GetAllViewsRecursive
    If v Is Button Then
        v.As(Button).Text = "Button " & count
        count = count + 1
    End If
Next

Scusami ma funziona anche se i botton sono inseriti tramite Designer, basta che vengano dichiarati nel sub Globals
B4X:
Sub Globals

  Dim buttons(13) as button

end sub

Sub Activity_Create(FirstTime as Boolean)
  for i = 0 to 13 -1
    ' buttons(i).Initialize("buttons")  <--- non serve se sono inserinti dal Designer
    buttons(i).tag = i
  next
end sub


Sub buttons_click
  dim b as button = sender
  bid = b.tag
  if bid=0 then
    buttons(3).enable=false

    buttons(5).enable=false
  endif

end sub
 

Sagenut

Expert
Licensed User
Longtime User
Scusami ma funziona anche se i botton sono inseriti tramite Designer, basta che vengano dichiarati nel sub Globals
Vero.
Se però devi ciclare molti button viene scomodo doverli scrivere tutti uno per uno nell'array.
La tua precisione è giusta e dovuta.
 

Massimo66

Member
Così potrebbe andare, ma devo creare la lista lBottoni una riga x volta.
Come si può creare una lista di oggetti button da passare alla sub setText ?
Il ciclo for net commentato ovviamente genera errore.

B4X:
Sub Globals
    Dim buttons(4) As Button
    Private Button1 As Button
    Private Button2 As Button
    Private Button3 As Button
    Private Button4 As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Dim lBottoni As List
    Activity.LoadLayout("test")
    
    lBottoni.Initialize
[B]'    For i = 1 To 4
''        lBottoni.Add($"Button${i}"$)
''    Next[/B]
    lBottoni.Add(Button1)
    lBottoni.Add(Button2)
    lBottoni.Add(Button3)
    lBottoni.Add(Button4)
    
    setText(lBottoni)
end sub

Sub setText( lBottoni() As List)
Dim i As Int
For Each btn As Button In lBottoni
        i=i+1
        btn.text = "BTN#" & i
        btn.Color=Colors.Green
    Next
End Sub
 

Lello1964

Well-Known Member
Licensed User
Longtime User
B4X:
Sub Process_Globals
   
End Sub

Sub Globals
    Dim buttons(4) As Button
    Private Button1 As Button
    Private Button2 As Button
    Private Button3 As Button
    Private Button4 As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Dim lBottoni As List
    Activity.LoadLayout("test")  
   
    buttons = Array As Button(Button1,Button2,Button3,Button4)
    setText(buttons)
End Sub

Sub setText( lBottoni() As Button)
    Dim i As Int
    For Each btn As Button In lBottoni
        i=i+1
        btn.text = "BTN#" & i
        btn.Color=Colors.Green
    Next
End Sub
 

Sagenut

Expert
Licensed User
Longtime User
@Massimo66
Funziona anche il metodo che hai usato tu.
C'era solo un piccolo errore
Questa riga
B4X:
Sub setText(lBottoni() As List)
deve diventare così
B4X:
Sub setText(lBottoni As List)
Una List è praticamente già un Array e non necessita delle ()
 

Massimo66

Member
Si infatti me ne sono accorto dopo. Però se dovessi sostituire queste istruzioni
B4X:
    lBottoni.Add(Button1)
    lBottoni.Add(Button2)
    lBottoni.Add(Button3)
    lBottoni.Add(Button4)
con un ciclo for . next come faresti a popolare la lista ?
 

Sagenut

Expert
Licensed User
Longtime User
Si infatti me ne sono accorto dopo. Però se dovessi sostituire queste istruzioni
B4X:
    lBottoni.Add(Button1)
    lBottoni.Add(Button2)
    lBottoni.Add(Button3)
    lBottoni.Add(Button4)
con un ciclo for . next come faresti a popolare la lista ?
Puoi farlo con un ciclo For Each come ti ho proposto qualche post prima.
B4X:
For Each v As View In Activity.GetAllViewsRecursive
    If v Is Button Then
        Lbottoni.Add(v.as(Button))
    End If
Next
Così però farebbe una iterazione su TUTTI i Button presenti.
Se hai necessità di creare piccoli gruppi isolati li dovresti raggruppare dentro a dei Panel (trasparenti se non vuoi che si vedano a Layout) e fare l'iterazione nel Panel del gruppo che ti interessa
B4X:
For Each v As View In PanelX.GetAllViewsRecursive 'PanelX sarà il nome del tuo Panel
    If v Is Button Then
        Lbottoni.Add(v.as(Button))
    End If
Next
 

ivanomonti

Expert
Licensed User
Longtime User
hai tempi usavo una list dove nel suo interno ci scrivevo i miei object e richiamavo object sulla base dell'indice, quindi se modificavo oggetto lo facevo sulla lista e poi rendevo le modifiche attive.

oggi però meglio creare le viste e richiamarle quando servono e molto più veloce e corretto a mio dire, poi tutti i metodi citati sopra sono ottimi
 

Sagenut

Expert
Licensed User
Longtime User
Ogni cosa può essere fatta in modi diversi.
L'importante è arrivare all'obiettivo con un metodo che capiamo e riusciamo a gestire.
Poi per migliorare il codice con nuovi metodi migliori c'è sempre tempo.
 
Top