[Gambas-user] Removing a runtime created control

ML d4t4full at gmail.com
Fri Nov 27 12:25:21 CET 2020


On 27/11/20 07:50, Rolf-Werner Eilert wrote:
> Am 27.11.20 um 11:34 schrieb KKing:
>> I've just run the following code in 3.12.2 on Debian10 LXDE and
>> Debian10 KDE.
>> NB I'm creating as just "Graphical Application" (i.e. not QT or GTK)
>>   - - - - - -
>> Private hToolButton As ToolButton
>>
>> Public Sub btnTest_Click()
>>    Dim intIndex As Integer
>>    For intIndex = 0 To 2
>>      hToolButton = New ToolButton(Me) As "My_Button"
>>      hToolButton.Top = 0 + (intIndex * 30)
>>      hToolButton.Left = 0
>>      hToolButton.Width = 300
>>      hToolButton.Height = 30
>>      hToolButton.Text = "MyButton" & CStr(intIndex)
>>    Next
>> End
>>
>> Public Sub btnRemove_Click()
>>
>>    Me["My_Button"].Delete
>>
>> End
>>
>> Public Sub My_Button_Click()
>>
>>    Message.Info("Hello")
>>
>> End
>>   - - - - - -
>>
>> On LXDE the btnTest generates the 3 buttons
>> click btnRemove once removes the first drawn button the remaining
>> buttons still function
>> click again and it removes the second drawn button the remaining
>> button still functions
>> click again and it removes the third and last drawn button.
>>
>> *** How could I just selectively remove a button based on index?
>>
>> NB the index for 0 to 2 is just for this example test, in desired
>> application there would be a variable and large number of buttons
>> determined by data and user interaction.
>>
>> As a workaround I could do
>>      hToolButton = New ToolButton(Me) As "My_Button" & CStr(intIndex)
>> which allows me to absolutely delete individual buttons but it means
>> instead of having one
>>      Public Sub My_Button_Click()
>> I would have to code a large number sub just in case needed, for this
>> example it would just need
>>      Public Sub My_Button0_Click()
>>      Public Sub My_Button1_Click()
>>      Public Sub My_Button2_Click()
>> But in the real application I may needs something like potentially 60
>> of them!
>>
>> ALSO
>> running the same code in Debian10 KDE does not work the same.
>> Clicking btnRemove once removes the last drawn button only (and the
>> first two buttons still work)
>> But when click btnRemove again to remove next button it complains
>> Me["My_Button"] is a null object
>> K.
>>
>> ----[ http://gambaswiki.org/wiki/doc/netiquette ]----
>>
>
> When I needed this, I deleted all objects from last to first with a
> for-next loop step -1.
> Like this:
>         Inc fldNr
>         mTxt.Resize(fldNr + 1)
>         mTxt[fldNr] = New TextBox(Maske) As "MaskeFeld"
>         mTxt[fldNr].Tag = wert[8] 'fldNr
>         mTxt[fldNr].ToolTip = wert[8]
>         mTxt[fldNr].X = Val(wert[2])
>         mTxt[fldNr].Y = Val(wert[3])
> And later this:
>   For i = mTxt.Count - 1 To 0 Step -1
>     mTxt[i].Delete
>   Next
>   mTxt.Clear
> As long as you point directly to the object, everything runs fine, and
> I included a separate counter (integer variable) to keep control over
> the absolute number of objects. Then delete them one-by-one
> referencing them with this counter.
> Regards
> Rolf

Try this (beware - not tested, pulled straight out of my brains, but I
think the concept gets through):

Private hToolButton As ToolButton
Private targetIndex As Integer    '<-- The form-scoped button index to
remove

Public Sub btnTest_Click()
   Dim intIndex As Integer
   For intIndex = 0 To 2
     hToolButton = New ToolButton(Me) As "My_Button"
     hToolButton.Top = 0 + (intIndex * 30)
     hToolButton.Left = 0
     hToolButton.Width = 300
     hToolButton.Height = 30
     hToolButton.Text = "MyButton" & CStr(intIndex)
     hToolButton.Tag = CStr(intIndex)    '<-- This here makes the
difference!
   Next
End

Public Sub btnRemove_Click()

   'Assume the index to kill is set somehow OUTSIDE THIS SUB in this
variable - The variable thus needs to be in the form's scope
   'You could have this test program show a textbox with the target
index to remove just to check this method works
   targetIndex = 1

   'Here, search for the proper tag-based index in the button array and
kill just that element.
   For intIndex = 0 To hToolButton.Lenght - 1 'Take any possible removed
indices into account (the array shrinks, indices change... but tags stay)
     If (hToolButton[intIndex].Tag = CStr(targetIndex)) Then
       hToolButton[intIndex].Delete
     End If
   Next

End

Public Sub My_Button_Click()

   Message.Info("Hello")

End

Another possibility would be having a Keyed Collection instead of an
array, and remove buttons from the Collection based on the key: No for
loops needed that way.

Hope it helps,
zxMarce.



More information about the User mailing list