Link to home
Start Free TrialLog in
Avatar of lep1
lep1

asked on

Handling Events for Dynamically-Created Controls

If I create a new control such as a checkbox dynamically at run time, how can I trap out an event such as Mousedown event, or the checked event?   This is not like adding a control to a form at design time before running, and then looking through the control's events to specify code to fire when those events are triggered.  Mainly, the issue is that whatever is done has to be done using a subroutine outside of the control creation sub.   Is addhandler used here (doubt it)  


   Dim chkbox As New CheckBox
   Form1.Controls.Add(chkbox)

Open in new window

SOLUTION
Avatar of appari
appari
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Avatar of Luis Pérez
Luis Pérez
Flag of Spain image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1
lep1

ASKER

Thanks for the comments thus far, however, I am providing the full picture below.  

The small form is dynamically created along with two checkboxlists.   There is a "select all" and "unselect all" checkbox above each checkbox list on the form so that users can select all the items in a given checkboxlist.  

I also provided a SelectAllChkBox subroutine that's used in the addhandler for the first "select all" checkbox.  The real trick is to be able to know what which list the "select all: check box is for (probably need a .tag= value that I can pick off), and then need to loop through all the items in the relevant checkboxlist control and check them.  

Another issue is that all of these controls are dynamic, so after the user clicks ok on this form, I need to be able to be able to spawn it again and show the same checked items in each (dynamically-created) checkboxlist.   Think a list of lists could be used in memory in which I simply loop through dictionary items to find out what's checked.    


 
 
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        'This button creates the checkboxlist form
        Dim list As New MyChecklistForm

        Call list.chkboxitemlists()

    End Sub

    Sub Selectallchkbox()   'This is an Addhandler subroutine for a checkbox
      
      'Need to determine source control that was checked here...
    End Sub

    Sub chkboxitemlists()  'This is the sub that creates checkboxes and checkboxlists
        Dim listform As New Form
        listform.Text = "CheckBoxList Form"
        listform.Show()

        Dim selectallcont As New CheckBox
        Dim selectallcat As New CheckBox
        Dim unselectallcont As New CheckBox
        Dim unselectallcat As New CheckBox
        selectallcont.Top = 30
        selectallcont.Left = 10
        selectallcat.Top = 30
        selectallcat.Left = 200
        unselectallcont.Top = 50
        unselectallcont.Left = 10
        unselectallcat.Top = 50
        unselectallcat.Left = 200
        selectallcont.Text = "Select all"
        selectallcat.Text = "Select all"
        unselectallcont.Text = "Unselect all"
        unselectallcat.Text = "Unselect all"
        AddHandler selectallcont.MouseDown, AddressOf Selectallchkbox

        listform.Controls.Add(selectallcont)
        listform.Controls.Add(selectallcat)
        listform.Controls.Add(unselectallcont)
        listform.Controls.Add(unselectallcat)


        Dim chk1 As New CheckedListBox
        Dim chk2 As New CheckedListBox
        chk1.Top = 80
        chk2.Top = 80
        chk1.Width = 180
        chk2.Width = 180
        chk1.Height = 500
        chk2.Height = 500
        listform.Width = 500
        listform.Height = 600
        chk1.Left = 10
        chk2.Left = 200
        Dim lbl1 As New Label
        Dim lbl2 As New Label
        lbl1.Top = 10
        lbl2.Top = 10
        lbl1.Left = 10
        lbl2.Left = 200
        lbl1.Text = "List 1"
        lbl2.Text = "List 2"
        'lbl1.Font = New Font(lbl1.Font, FontStyle.Bold)
        'lbl2.Font = New Font(lbl2.Font, FontStyle.Bold)
        lbl1.Font = New System.Drawing.Font("Arial", 12)
        lbl1.Font = New System.Drawing.Font(lbl1.Font, FontStyle.Bold)
        lbl2.Font = New System.Drawing.Font("Arial", 12)
        lbl2.Font = New System.Drawing.Font(lbl2.Font, FontStyle.Bold)
        listform.Controls.Add(chk1)
        listform.Controls.Add(chk2)
        listform.Controls.Add(lbl1)
        listform.Controls.Add(lbl2)

        Dim i As Integer
        For i = 1 To 50
            chk1.Items.Add("item" & i)
            chk2.Items.Add("item" & i)
        Next
        Dim btn1 As New Button
        listform.Controls.Add(btn1)
        btn1.Top = 50
        btn1.Left = 400
        btn1.Text = "OK"

    End Sub

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

Because the length of the checkbox list and the items in each change a lot.  There can also be an unlimited number of these forms based on what the user wants.  Hence, the forms need to be OOP, cleaned after garbage collection, and spawned whenever a user load an option form to change the checked items.  This is normal capability in a lot of codes but it has to be OOP and killable via GC
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

Thanks, idle mind!  Before closing  (I will double the points) recall the buttons and connecting lines you helped with.  Well, this form with checkbox lists will actually be spawned upon right clicking the button and selecting the menu command for button options.  Therefore many buttons will have their own specific checkbox list form that appears when the user wants to change the items checked for that button.  So maybe there is a way to draw the tag from the original moveable button, affix it to the checkbox lists that are spawned in this new dynamic form, and finally I will need to loop through the checkbox lists when the user clicks ok to exit this option form.  ( the selected unselected choices then have to be used to modify the results in memory).  Then any time a user right clicks a moveable button ( with its lines ) and selects the edit option, what they selected previously will show.  

The bad part is that I also have to dump these contents to a project file that can be used to load into memory the checkbox list items and what's checked.

Thus could you provide a sub that dumps everything to disk ( with a file name) and a sub to load the checkbox lists into memory -/ so the user can resume work with last saved.  

This is stuff I use all day long in a lot of software but its another thing coding everything.

Should I make a new question instead and paste the code you provided here?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

Let me code a little and close this out. Will get back but can't look at from now till tonight maybe very late
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

Can't "chk1" and "chk2" come from a moveable button's .tag value, since that outside this checkbox list form class?

Also, if the checklist form is closed on clicking ok, then how will the checked/unchecked status for each dynamic checkbox list ( associated with each moveable button ) if garbage collection kills them?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

I pasted your MyChecklistForm Class into my code as its own Class, and the compiler did not like the Me. syntax, as all of the Me. were underlined with blue exception throws.   Does not Me. only work for the fixed Form1?

Should the btnchk addhandler subroutines be in the Form1 class, or the CheckListForm class?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

Closest implementation I can get to work is as follows.   The only exception being thrown is a blue underline under showdialog in button1, which is in Form1:


    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim chkList As New MyChecklistForm
        '*****Error on next line (blue underline) is e.g., "ShowDialog is not a member of Project1.MyChecklistForm
        If chkList.ShowDialog = Windows.Forms.DialogResult.OK Then
            Debug.Print("chk1")
            For i As Integer = 0 To chkList.chk1.Items.Count - 1
                If chkList.chk1.GetItemChecked(i) Then
                    Debug.Print(chkList.chk1.Items(i))
                End If
            Next

            Debug.Print("chk2")
            For i As Integer = 0 To chkList.chk2.Items.Count - 1
                If chkList.chk2.GetItemChecked(i) Then
                    Debug.Print(chkList.chk2.Items(i))
                End If
            Next
        End If
    End Sub


Public Class MyChecklistForm
    Public ChecklistForm As New Form
    Public chk1 As New CheckedListBox
    Public chk2 As New CheckedListBox
    Sub Checklist()
        ChecklistForm.Text = "CheckBoxList Form"
        chk1.Top = 80
        chk2.Top = 80
        chk1.Width = 180
        chk2.Width = 180
        chk1.Height = 500
        chk2.Height = 500
        ChecklistForm.Width = 500
        ChecklistForm.Height = 600
        chk1.Left = 10
        chk2.Left = 200
        Dim lbl1 As New Label
        Dim lbl2 As New Label
        lbl1.Top = 10
        lbl2.Top = 10
        lbl1.Left = 10
        lbl2.Left = 200
        lbl1.Text = "List 1"
        lbl2.Text = "List 2"
        'lbl1.Font = New Font(lbl1.Font, FontStyle.Bold)
        'lbl2.Font = New Font(lbl2.Font, FontStyle.Bold)
        lbl1.Font = New System.Drawing.Font("Arial", 12)
        lbl1.Font = New System.Drawing.Font(lbl1.Font, FontStyle.Bold)
        lbl2.Font = New System.Drawing.Font("Arial", 12)
        lbl2.Font = New System.Drawing.Font(lbl2.Font, FontStyle.Bold)
        ChecklistForm.Controls.Add(chk1)
        ChecklistForm.Controls.Add(chk2)
        ChecklistForm.Controls.Add(lbl1)
        ChecklistForm.Controls.Add(lbl2)

        Dim i As Integer
        For i = 1 To 50
            chk1.Items.Add("item" & i)
            chk2.Items.Add("item" & i)
        Next

        Dim btn1 As New Button
        ChecklistForm.Controls.Add(btn1)
        btn1.Top = 50
        btn1.Left = 400
        btn1.Text = "OK"
        AddHandler btn1.Click, AddressOf btnOK_Click

        Dim selectallcont As New Button
        Dim selectallcat As New Button
        Dim unselectallcont As New Button
        Dim unselectallcat As New Button
        selectallcont.Top = 30
        selectallcont.Left = 10
        selectallcat.Top = 30
        selectallcat.Left = 200
        unselectallcont.Top = 50
        unselectallcont.Left = 10
        unselectallcat.Top = 50
        unselectallcat.Left = 200
        selectallcont.Text = "Select all"
        selectallcat.Text = "Select all"
        unselectallcont.Text = "Unselect all"
        unselectallcat.Text = "Unselect all"

        selectallcont.Tag = chk1
        unselectallcont.Tag = chk1
        AddHandler selectallcont.Click, AddressOf btnSelect_Click
        AddHandler unselectallcont.Click, AddressOf btnSelect_Click
        selectallcat.Tag = chk2
        unselectallcat.Tag = chk2
        AddHandler selectallcat.Click, AddressOf btnSelect_Click
        AddHandler unselectallcat.Click, AddressOf btnSelect_Click

        ChecklistForm.Controls.Add(selectallcont)
        ChecklistForm.Controls.Add(selectallcat)
        ChecklistForm.Controls.Add(unselectallcont)
        ChecklistForm.Controls.Add(unselectallcat)
        ChecklistForm.DialogResult = Windows.Forms.DialogResult.OK
    End Sub
    Private Sub btnSelect_Click(sender As Object, e As System.EventArgs)
        Dim btn As Button = CType(sender, Button)
        Dim chk As CheckedListBox = CType(btn.Tag, CheckedListBox)
        For i As Integer = 0 To chk.Items.Count - 1
            chk.SetItemChecked(i, btn.Text.StartsWith("Select"))
        Next
    End Sub

    Private Sub btnOK_Click(sender As Object, e As System.EventArgs)
        ChecklistForm.DialogResult = Windows.Forms.DialogResult.OK
    End Sub

End Class

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

Got it! that worked --> I added a Windows Form and named it MyCheckListForm.vb. and pasted your class code into the class code for the form.  Obviously this class code is no different from the Form1 class code.    

Some remaining items.  In response to your question, sometimes only one checkbox is needed.  

What do you recommend doing when the user clicks on the OK button in the checklist form?   What is the appropriate way to set show=false for a dynamically spawned form like this.  

Last, if a user populates Form1 with a lot of "moveable buttons" -- each of which has its own checkboxlist form, how are the checked items that were set stored in memory?  Is there no problem loading many of the checklist forms and leaving them in RAM memory?
Avatar of lep1

ASKER

Actually, this checklistform is one variety of what a user needs to see when the contextmenu of a moveable button is right-clicked.  Sometimes the popupform will have radiobuttons, textboxes, and generic checkboxes for options specific to that button (task).   This is why I defined a generic form inside the class -- because I can't have many form.vb's in the project since it kills memory.  rather, I would like to instantiate a class which is actually a custom form with different controls on it.  

All of the popupforms are simply to set options for all the moveable buttons.  And they will be different.   Hence, given this, I am wondering if your added .vb Windows Form that we named MyCheckList form sholuld be removed and then spawn a generic form when a new class is spawned?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

So the trick is adding form dynamically, using a specific custom size of each form (based on the number of controls on it), and then making sure the options specified by the user for each "option" form is memorized at run time.   This all needs to be dumped to a project file before quitting as well. When loading the project, all of the specified "option forms" for the same moveable buttons need to be loaded.  

As you are aware, a lot of commercial code implements these capabilities.   It's a lot of work, but eventially it can be completed.  

So wouldn't I be better off using Dim myform as New Form with each class that's specific to each option form (for a moveable button)?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

>How is the information for each button currently being stored?

Write now nothing is OOP and all of the options are sitting together in group boxes on many forms -- since the calculations had to be developed/verified.   Indeed, OOP is the way to go.

>Are there any base type functionality or pieces of information for the buttons common to all buttons?

The checklist popupform can be used on many buttons, and maybe there would be 8-10 total forms.  However, I can disable inappropriate options.   Would there be a problem add these 8-10 form.vb to the project, save options in a dictionary (list), and then kill the form when done after usage via GC?   When loading I could fetch from each of 8-10 dictionaries?

>Should an Interface() be created that all buttons must adhere to?

Don't know, can you give me link to a good interface description.   I have some OOP books for vb.net as well.

I think if popupforms could be killed for GC it won't be so bad.  As long as I fetch options from each popup form before it's killed and write to a list (dictionary) it may be ok?

One thing I do know is that having 10 forms with 100-200 controls loaded in memory is very innefficient.   Commercial codes tackle this problem -  so how is this done in industry for large codes with workflow?
Avatar of lep1

ASKER

Oh, one thing that came to mind..--> your Checklist form that is a class that was added as a Windows form is hogging memory at run time.   Would that take up more memory than a form spawned dynamically using Dim myform as New Form?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lep1

ASKER

The points for this question should be at least 10000, since Idle_Mind provided lengthy code segments with desriptions