Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 443
  • Last Modified:

Adding multiple user controls with diff variables.

I have a user control that want to fill a flow layout panel, for each listbox item selected. The user control consists of 2 labels and a button. The 1st label contains the text of the item selected - this part I got working, as I keep selecting new items in the listbox I want a new control to be added to the flow layout panel, currently it overwrite the first object in the FLP, I had this working once - not sure what I had changed, thanks for the help.

Private Sub lsbTasks_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lsbTasks.SelectedIndexChanged
        start = DateTime.Now
        Dim task As String = lsbTasks.SelectedItem
        t_Timer.lblTask.Text = task
        flpTasks.Controls.Add(t_Timer)
        StartClock() ' timer control
    End Sub

Open in new window

0
Hawkvalley1
Asked:
Hawkvalley1
  • 11
  • 10
1 Solution
 
Bob LearnedCommented:
I don't see where you would be creating new instances of the control.
0
 
Hawkvalley1Author Commented:
Friend WithEvents t_Timer as new TaskTimer which is the User Control I built. It is added at the Class level of the form calling it.
0
 
Hawkvalley1Author Commented:
And I accually moved to a button click event instead of the above.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Bob LearnedCommented:
You would need to create new instances each time, and not use a module-level variable.
0
 
Hawkvalley1Author Commented:
ok, I need the variable in a Timer_tick event, and I haven't even started on the button events which is why I went with the WithEvent, I was thinking I will need an addhandler for the button event right?
0
 
Bob LearnedCommented:
It is difficult to suggest the "correct" course of action, without really understanding what you are trying to do.
0
 
Hawkvalley1Author Commented:
ok, I have a FlowLayoutPanel(FLP) to place the user control, each user control has 2 labels and a button, the first label holds the text from the listbox item, the second label is a label that updates itself based on a timer control - these I have working. the button I want to close the specific instance of the user control in the FLP and send the text of the second label to a diff. listbox. When I use the 'new' instance in the button event(where my code builds the user control and places it on the FLP on the form) I get multiple user controls but not able to use the timer function as it can't refer to the instance of the user control's second label  - was wondering if I can use an addhandler for this.
0
 
Bob LearnedCommented:
And, how does the Timer come into play here?
0
 
Hawkvalley1Author Commented:
This is on the main form that calls the user control. as you can see line 4 has the t_Timer.lblTaskTimer this is the label that updates like a elapsed timer, basically counts the time the user control has been in existance. So since this label is called from outside the code block where the user control was initilized it can't reference it without the class declaration - and then we get the problem in making instants within the button event. So how do we fix this?
Public Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim ts As TimeSpan = DateTime.Now - start
        Dim time As DateTime = DateTime.Now.Date + ts
        t_Timer.lblTaskTimer.Text = time.ToString("HH:mm:ss")
    End Sub
 
' code from within the button_click event
 Dim unit As String = lsbUnitsAssigned.SelectedItem
            Dim task As String = lsbTasks.SelectedItem
            lsbReport.Items.Add(Format(TimeOfDay, " ( HH:mm:ss ) : ") & unit &  task & txtAdditionalInfo.Text)
            start = DateTime.Now ' class variable that is defined here and starts the clock(timer)
            t_Timer.lblTask.Text = task.ToString
            flpTasks.Controls.Add(t_Timer)
            StartClock() ' this is the timer 1 sub that starts the timer.

Open in new window

0
 
Bob LearnedCommented:
If you are trying to time things, you might want to use a System.Diagnostics.Stopwatch, instead of a Timer, since it is high-resolution, and self contained.
0
 
Hawkvalley1Author Commented:
Ok, how about I lose the user control, and make and button who's text is the combination of the other labels that are created during the button event on the main form that enters the FLP then everything is controlled by the form code and no user control is needed?  And use the stopwatch for the timer. This sound like a better plan? The reason for the FLP is there will be several events being timed at the same time.
0
 
Hawkvalley1Author Commented:
ok, I got multiple controls added FLP and left the class declaration of t_Timer, but the 2nd control stops  the first control's timer.
0
 
Bob LearnedCommented:
My friend, I don't know what to tell you.  Can you attach a .png screen shot of what you mean?
0
 
Hawkvalley1Author Commented:
Well, I have the class level declaration of t_timer as TaskTimer(the user control), then derclare it new(t_Timer = new TaskTimer) in the button event, which lets the FLP add new ones(TaskTimer) as I hit the button, however the timer that it running on the first one stops when the second one is added to the FLP, and I tried the same technique to the timer, but to no avail - which is running on a seperate thread - right.

So in the picture, you see 2 user controls - 2 labels and the button, the time on the first counts until the 2nd control is added, then it counts.
FLP.png
0
 
Bob LearnedCommented:
You are probably looking for something like this

TaskTimer.vb
Imports System.ComponentModel
 
Public Class TaskTimer
 
    Private m_timerSpan As New TimeSpan()
 
    Public Property TaskTitle() As String
        Get
            Return Me.TitleLabel.Text
        End Get
        Set(ByVal value As String)
            Me.TitleLabel.Text = value
        End Set
    End Property
 
    <Browsable(False)> _
    Public ReadOnly Property TaskTime() As String
        Get
            Return Me.TimeLabel.Text
        End Get
    End Property
 
    Private Sub InternalTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InternalTimer.Tick
        m_timerSpan = m_timerSpan.Add(New TimeSpan(0, 0, 1))
 
        Me.TimeLabel.Text = m_timerSpan.ToString()
 
        Application.DoEvents()
    End Sub
 
    Private Sub StartStopCheckButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartStopCheckButton.CheckedChanged
        Me.InternalTimer.Enabled = Me.StartStopCheckButton.Checked
 
        If Me.StartStopCheckButton.Checked Then
            Me.StartStopCheckButton.Text = "&Stop"
        Else
            Me.StartStopCheckButton.Text = "&Start"
        End If
    End Sub
 
End Class

Open in new window

0
 
Bob LearnedCommented:
TaskTimer.Designer.vb


<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class TaskTimer
    Inherits System.Windows.Forms.UserControl
 
    'UserControl overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub
 
    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer
 
    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.TitleLabel = New System.Windows.Forms.Label
        Me.TimeLabel = New System.Windows.Forms.Label
        Me.InternalTimer = New System.Windows.Forms.Timer(Me.components)
        Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel
        Me.StartStopCheckButton = New System.Windows.Forms.CheckBox
        Me.TableLayoutPanel1.SuspendLayout()
        Me.SuspendLayout()
        '
        'TitleLabel
        '
        Me.TitleLabel.BackColor = System.Drawing.Color.Transparent
        Me.TitleLabel.Dock = System.Windows.Forms.DockStyle.Fill
        Me.TitleLabel.ForeColor = System.Drawing.SystemColors.ActiveCaptionText
        Me.TitleLabel.Location = New System.Drawing.Point(3, 0)
        Me.TitleLabel.Name = "TitleLabel"
        Me.TitleLabel.Size = New System.Drawing.Size(110, 44)
        Me.TitleLabel.TabIndex = 0
        Me.TitleLabel.Text = "Test"
        Me.TitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'TimeLabel
        '
        Me.TimeLabel.BackColor = System.Drawing.Color.Transparent
        Me.TimeLabel.Dock = System.Windows.Forms.DockStyle.Fill
        Me.TimeLabel.ForeColor = System.Drawing.SystemColors.ActiveCaptionText
        Me.TimeLabel.Location = New System.Drawing.Point(119, 0)
        Me.TimeLabel.Name = "TimeLabel"
        Me.TimeLabel.Size = New System.Drawing.Size(110, 44)
        Me.TimeLabel.TabIndex = 1
        Me.TimeLabel.Text = "00:00:00"
        Me.TimeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight
        '
        'InternalTimer
        '
        Me.InternalTimer.Interval = 1000
        '
        'TableLayoutPanel1
        '
        Me.TableLayoutPanel1.BackColor = System.Drawing.SystemColors.ActiveCaption
        Me.TableLayoutPanel1.ColumnCount = 3
        Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
        Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
        Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
        Me.TableLayoutPanel1.Controls.Add(Me.TitleLabel, 0, 0)
        Me.TableLayoutPanel1.Controls.Add(Me.TimeLabel, 1, 0)
        Me.TableLayoutPanel1.Controls.Add(Me.StartStopCheckButton, 2, 0)
        Me.TableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
        Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0)
        Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
        Me.TableLayoutPanel1.RowCount = 1
        Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
        Me.TableLayoutPanel1.Size = New System.Drawing.Size(348, 44)
        Me.TableLayoutPanel1.TabIndex = 4
        '
        'StartStopCheckButton
        '
        Me.StartStopCheckButton.Appearance = System.Windows.Forms.Appearance.Button
        Me.StartStopCheckButton.AutoSize = True
        Me.StartStopCheckButton.Dock = System.Windows.Forms.DockStyle.Fill
        Me.StartStopCheckButton.Location = New System.Drawing.Point(235, 3)
        Me.StartStopCheckButton.Name = "StartStopCheckButton"
        Me.StartStopCheckButton.Size = New System.Drawing.Size(110, 38)
        Me.StartStopCheckButton.TabIndex = 2
        Me.StartStopCheckButton.Text = "&Start"
        Me.StartStopCheckButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        Me.StartStopCheckButton.UseVisualStyleBackColor = True
        '
        'TaskTimer
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 18.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
        Me.Controls.Add(Me.TableLayoutPanel1)
        Me.Font = New System.Drawing.Font("Trebuchet MS", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
        Me.Name = "TaskTimer"
        Me.Size = New System.Drawing.Size(348, 44)
        Me.TableLayoutPanel1.ResumeLayout(False)
        Me.TableLayoutPanel1.PerformLayout()
        Me.ResumeLayout(False)
 
    End Sub
    Friend WithEvents TableLayoutPanel1 As System.Windows.Forms.TableLayoutPanel
    Private WithEvents TitleLabel As System.Windows.Forms.Label
    Private WithEvents TimeLabel As System.Windows.Forms.Label
    Private WithEvents InternalTimer As System.Windows.Forms.Timer
    Friend WithEvents StartStopCheckButton As System.Windows.Forms.CheckBox
 
End Class

Open in new window

0
 
Bob LearnedCommented:
Screen shot:


TaskTimer.png
0
 
Hawkvalley1Author Commented:
instead of the checkbox, I want a button that will stop the clock and close the user control from the FLP. And with this coding I will not need a timer on the main form - right? Oh and the time is to start when it is loaded to the FLP. I can use a 'remove button on the main screen for removing the controls from the FLP if that is easier.
0
 
Bob LearnedCommented:
The CheckBox is a button in this case, it just shows the state, so that you can tell when it is checked (pressed).  The timer is part of the user control, so you get separate Timers instances, instead of sharing the same one.
0
 
Hawkvalley1Author Commented:
By the way it is working great, I'll work on some things and let you know how it is doing.
0
 
Hawkvalley1Author Commented:
It works great as is, going to make some minor changes, thanks, sorry for the long-winded process.
0

Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 11
  • 10
Tackle projects and never again get stuck behind a technical roadblock.
Join Now