Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Multiple User Controls added to flowLayoutPanel, need the checkedchanged events for each UC.

Posted on 2008-10-12
17
Medium Priority
?
581 Views
Last Modified: 2012-05-05
I have a User Control that has two labels and a checkbox, I have done it two diff ways to get the checkchanged event for the checkbox (Public Event/Raise Event, or the addhandler checkedchanged event) they both work for just one UC but when I add multiple UCs to the form the event only calls the last UC that was added to the flowLayoutPanel. How can I use each checkbox for each UC, the things I am trying to accomplish are sending the label text to a listbox(this I got-when using one UC)
and change the backcolor in a listview for the other label item(this I got-when using one UC).
0
Comment
Question by:Hawkvalley1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 6
17 Comments
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 22697806
Show us your code where you use AddHandler() to handle multiple UserControls....
0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22697871
well I cant, I'm at work, but it goes like this:

in the button event that creates the UC,
t_timer as New TaskTimer
t_timer.lbl1 = "something"
t_timer.lbl2 = "something else"
flp1.control.add(t-timer)
addhandler t-timer.ckbStop.CheckedChanged, address of _ ckbStop_CheckedChanged

and I build the Sub named above and then add the code.
this works better than the Public Event/Raise Event
0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22697875
I know why it functions the way it does, there is only one sub(Addhandler) for all the UCs, this is why I ask is there something else I can do?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22697952
But the weird thing is the labels for each UC receive there text from a listbox item(lbl1) and a listview item(lbl2) that was selected before the button event makes the UC, then when I check the checkbox on the UC(button style) the timer stops(lbl3-we didnt talk about this but its fine) and the text in the labels are sent to a different listbox - based on which UC.checkbox - so each UC recognizes the diff text in them, but the thing that isn't working is the code to change the listview backcolor(index of the text(UC.lbl2)-using  FindItemWithText method) for the second labels text which is where it came from-this helps me find the index so I can change the backcolor back to what is was. Sorry if this confusing.
0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22697972
opps, I digress it does not recognize the text of each UC, just the last one so disregard the last comment...I pay better attention...
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 22699047
These two statements of yours don't seem to go together:

    "there is only one sub(Addhandler) for all the UCs"

Followed by:

    "in the button event that creates the UC
    ...
    addhandler t-timer.ckbStop.CheckedChanged, address of _ ckbStop_CheckedChanged"

It looks like you are using AddHandler() EVERY time you create a New UserControl.

If this is the case then all of the CheckBoxes will fire the same sub.  If you want to know which UserControl was the "source" of the event then try something like this in your ckbStop_CheckedChanged() sub:

    ' this assumes the CheckBox is DIRECTLY contained by the UserControl (not in a Panel for example)
    Dim cb As CheckBox = DirectCast(sender, CheckBox)
    Dim uc As YourUserControlTypeHere = DirectCast(cb.Parent, YourUserControlTypeHere)
    ' ...interrograte "uc" as necessary...

Does that help?...not sure what you need here...

0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22699190
You are heading in the right path, and what you are saying makes some sense. So what else goes in the checkChanged Sub - just these statements or the code I want to execute? You are correct about the checkbox - it and 3 labels are in the UserControl. a timer is also running in the UC - lbl3(TimeSpan), I can fill the lbl's with text from the sources on the main form and the timer runs, the 1st lbl is the item text from a listview, the 2nd lbl is just text, when I check the checkbox(button style): it stops the timer, uses the text in lbl1 to FindItemWithText.index to change the backcolor of the listview item of the same text(which was changed earlier), sends all the lbl's text to a listbox and if I get all these working I also want to make the specific UC clear from the flowLayoutPanel, hope this is clearer...

Thanks for the help.
0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22699990
Ok, I added the code you supplied to the checkchanged_event on the UserControl and it isn't working yet, I have a Public Event on the UC to expose the checkchanged_event, and here is the code I have:
'===UserControl=== 
Private Sub ckbStop_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ckbStop.CheckedChanged
        Dim cb As CheckBox = DirectCast(sender, CheckBox)
        Dim tt As TaskTimer = DirectCast(cb.Parent, TaskTimer)
        Me.Timer1.Enabled = Me.ckbStop.Checked
        If Me.ckbStop.Checked Then
            Me.ckbStop.Text = "Stop"
        Else
            Me.ckbStop.Text = "Done"
            Me.ckbStop.Enabled = False
            RaiseEvent TaskCheckedChanged(sender)
        End If
    End Sub
 Public Event TaskCheckedChanged(ByVal TheCheckChanged As CheckBox)
'===MainForm===
Private Sub t_Timer_TaskCheckedChanged(ByVal TheCheckChanged As System.Windows.Forms.CheckBox) Handles t_Timer.TaskCheckedChanged
        Dim timeStop As String = t_Timer.lblUnit.Text & "Completed time: " & t_Timer.lblTaskTimer.Text
        lsbReport.Items.Add(Format(TimeOfDay, " ( HH:mm:ss ) : ") & timeStop)
        ltvUnits.Items(ltvUnits.FindItemWithText(t_Timer.lblUnit.Text, False, 0).Index).BackColor = Color.LightGreen
    End Sub
'the button that creates the UserControl
Public Sub btnAddSelectedTask_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddSelectedTask.Click
        Try
              If ltvUnits.SelectedIndices Is Nothing Then
                MsgBox("Select a Unit first!")
            ElseIf lsbTasks.SelectedIndex = -1 Then
                MsgBox("Select a Task!")
            Else
                t_Timer = New TaskTimer
                Dim unit As String
                Dim unitIndex As ListView.SelectedIndexCollection = ltvUnits.SelectedIndices
                Dim index As Integer
                For Each index In unitIndex
                    ltvUnits.Items(index).BackColor = Color.Red
                Next
                unit = ltvUnits.Items(index).Text
                Dim task As String = lsbTasks.SelectedItem
                lsbReport.Items.Add(Format(TimeOfDay, " ( HH:mm:ss ) : ") & unit.TrimEnd(" ") & a & task & b & " : " & txtAdditionalInfo.Text)
                t_Timer.lblUnit.Text = unit.TrimEnd(" ")
                t_Timer.lblTask.Text = task.ToString
                flpTasks.Controls.Add(t_Timer)
            End If
            lsbTasks.SelectedIndex = -1
            txtAdditionalInfo.Text = String.Empty
        Catch
        End Try
    End Sub

Open in new window

0
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 2000 total points
ID: 22717005
I think this is more what you are after in the UserControl:

    Public Class TaskTimer ' (UserControl)

        Public Event TaskCheckedChanged(ByVal TT As TaskTimer)

        Private Sub ckbStop_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ckbStop.CheckedChanged
            Me.Timer1.Enabled = Me.ckbStop.Checked
            If Me.ckbStop.Checked Then
                Me.ckbStop.Text = "Stop"
            Else
                Me.ckbStop.Text = "Done"
                Me.ckbStop.Enabled = False
                RaiseEvent TaskCheckedChanged(Me)
            End If
        End Sub
 
    End Class

And something like this in the MainForm:

    '===MainForm===
    Private Sub TT_TaskCheckedChanged(ByVal TT As TaskTimer)
        Dim timeStop As String = TT.lblUnit.Text & "Completed time: " & TT.lblTaskTimer.Text
        lsbReport.Items.Add(Format(TimeOfDay, " ( HH:mm:ss ) : ") & timeStop)
        ltvUnits.Items(ltvUnits.FindItemWithText(TT.lblUnit.Text, False, 0).Index).BackColor = Color.LightGreen

        ' ..do something else with "TT" if necessary...
        ' If you wanted to remove it from the flowpanel:
        flpTasks.Controls.Add(TT)
    End Sub

    'the button that creates the UserControl
    Public Sub btnAddSelectedTask_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddSelectedTask.Click
        Try
            If ltvUnits.SelectedIndices Is Nothing Then
                MsgBox("Select a Unit first!")
            ElseIf lsbTasks.SelectedIndex = -1 Then
                MsgBox("Select a Task!")
            Else
                Dim unit As String
                Dim unitIndex As ListView.SelectedIndexCollection = ltvUnits.SelectedIndices
                Dim index As Integer
                For Each index In unitIndex
                    ltvUnits.Items(index).BackColor = Color.Red
                Next
                unit = ltvUnits.Items(index).Text
                Dim task As String = lsbTasks.SelectedItem
                lsbReport.Items.Add(Format(TimeOfDay, " ( HH:mm:ss ) : ") & unit.TrimEnd(" ") & a & task & b & " : " & txtAdditionalInfo.Text)

                Dim t_Timer As New TaskTimer
                t_Timer.lblUnit.Text = unit.TrimEnd(" ")
                t_Timer.lblTask.Text = task.ToString
                AddHandler t_Timer.TaskCheckedChanged, AddressOf Me.TT_TaskCheckedChanged
                flpTasks.Controls.Add(t_Timer)
            End If
            lsbTasks.SelectedIndex = -1
            txtAdditionalInfo.Text = String.Empty
        Catch
        End Try
    End Sub
0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22717233
I have tried the exact code, and on the addhandler(main form) the address of TT_checkedChanged I get a error: does not have a signature compatible with delegate sub eventhandler(sender, e).


0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 22717649
Then you haven't used the EXACT code...   =)

Note that I changed the signature of the Event...so you have to change the signature of the method as well.  Also noted that it does NOT have the "Handles ..." part on it anymore.

Here is the signature of the Event in the UserControl:

    Public Event TaskCheckedChanged(ByVal TT As TaskTimer)

And here is the method being pointed to by AddHandler():

    Private Sub TT_TaskCheckedChanged(ByVal TT As TaskTimer)

They both have the same signature...

0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22724589
Well I'm not sure what to tell you, I have both of the signatures like you do and I get the squigly lines under the addressOf statement. And my addhandler is where you have yours, I have double and triple checked my code and yours and the problem remains - sorry for the hassle - it just isn't making sense.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 22724702
It's no problem...we'll just have to see your current code incarnation then...   =)
0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22725542
I did change the checkbox to a button(what I wanted first place-someone else helping me wanted me to use the checkbox)
===User Control===
Public Class TaskTimer
Public Event TaskStop(TT as TaskTimer)

in the btnStop_click event...
RaiseEvent TaskStop(Me)

===Main Form===
Privat Sub TT_TaskStop(TT as TaskTimer)
'code to do some work

in the btnSelectTask_Click event...

AddHandler t_Timer.btnStop.click, ~AddressOf Me.TT_TaskStop~
between the ~~ is where the squigle lines are and the exact statement when I hower over it is

" Method 'Private Sub TT_TaskStop(TT as TaskTimer)' does not have the a signature compatible with the delegate ' Delegate Sub EventHandler(sender as object, e as system.eventargs)'."

So following your setup I used the same format
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 22725750
Lol....ok...

In my code, I am wiring the TaskTimer.TaskCheckedChanged() Event:

    AddHandler t_Timer.TaskCheckedChanged, AddressOf Me.TT_TaskCheckedChanged

In your code, you are wiring the Button.Click() Event:

    AddHandler t_Timer.btnStop.click, AddressOf Me.TT_TaskStop



The signature for the TaskTimer.TaskCheckedChanged() Event is:

    Public Event TaskStop(TT as TaskTimer)

The signature for the Button.Click() Event is:

    Public Event Click(Sender As Object, e As System.EventArgs)

See the difference?  The signatures do NOT match.  =)

Just raise the TaskCheckedChanged() Event from your Button Click sub in your UserControl:

    Public Class TaskTimer ' (UserControl)

        Public Event TaskCheckedChanged(ByVal TT As TaskTimer)

        Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
            ... possibly more code ...
            RaiseEvent TaskCheckedChanged(Me)
        End Sub

    End Class

The AddHandler() line will still look like my original code then:

    AddHandler t_Timer.TaskCheckedChanged, AddressOf Me.TT_TaskCheckedChanged
0
 
LVL 9

Author Comment

by:Hawkvalley1
ID: 22725845
Ok, it is done, works perfectly, sorry if I had missed that part of your code from earlier, I had wondered what was calling the TaskTimer event into the main form - this makes sense to me now.  
0
 
LVL 9

Author Closing Comment

by:Hawkvalley1
ID: 31505439
Thanks, you rock!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question