Solved

Changing textbox from a thread. VB.Net

Posted on 2004-08-23
19
203 Views
Last Modified: 2010-05-02
I cant change the text in a label or textbox from a thread.

Description of what I have.
I have two classes "VIPList", and another Public Class "BackgroundQuery"

When the thread has completed it sends back 2 strings using a public event. if there was no error this process works 100% great. If there is an error the event handler in "VIPList" is supposed to change the textbox text to one of the 2 strings passed from the thread. (instead of being dumped to a txt file) My problem is the text gets passed but not set. The textbox always ends up empty.

Any Ideas?
Code available if necessary.
0
Comment
Question by:gbarcalow
  • 10
  • 9
19 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11873488
>> Code available if necessary.

We need to see your code.  The interaction you describe is complex and the problem could be anywhere in the process.

=)
Idle_Mind
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11873615
Public Class VIPList
    Inherits System.Windows.Forms.Form
    ...
    Private WithEvents oBGProcess As BackgroundQuery
    Private tMain As Thread

    'button click starts thread

    Private Sub QueryDone(ByVal sDateFrom As String, ByVal sDateTo As String) Handles oBGProcess.eQueryComplete
    ....
    If sDateFrom = "Error" Then
            'This is the code that doesnt work.
            txtError.Visible = True
            txtError.Text = "ERROR: " & vbCrLf & sDateTo
    Else
            'This code works fine
            SaveSetting("CSRT", User_ID, "VIP Estimated", tTimeStarted & "~" & Now)
            ProgressBar1.Value = ProgressBar1.Maximum

            Dim proc As Process
            If File.Exists(Application.StartupPath & "\" & sDateFrom & "_" & sDateTo & ".csv") Then _
            proc.Start(Application.StartupPath & "\" & sDateFrom & "_" & sDateTo & ".csv")
    End If  

    End Sub
End Class

Public Class BackgroundQuery

    Public Event eQueryComplete(ByVal sDateFrom As String, ByVal sDateTo As String)

    ....

    Public Sub MainQuery()
        Dim GBAScm As New OleDb.OleDbCommand
        Dim GBASdr As OleDb.OleDbDataReader

        'Go do it
        Try
            GBAScn.Open()
            GBAScm.Connection = GBAScn

            'Query Here

            'Write Query Results to text file here

        Catch ex As Exception
            RaiseEvent eQueryComplete("Error", ex.Message)
        Finally
            If Not dr.IsClosed Then dr.Close()
            GBAScn.Close()
            RaiseEvent eQueryComplete(sDateFrom, sDateTo)
        End Try
    End Sub

End Class
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11873787
The Finally block is always run, regardless of any actions occurring in preceding Catch blocks so I think what is happening is your error event is being raised but you are receiving another one immediately after that from the finally block.  Since there was error in the query, the values will be empty.

Try it the way I have it below instead...

Regards,

Idle_Mind

    Public Sub MainQuery()
        Dim GBAScm As New OleDb.OleDbCommand
        Dim GBASdr As OleDb.OleDbDataReader

        'Go do it
        Try
            GBAScn.Open()
            GBAScm.Connection = GBAScn

            'Query Here

            'Write Query Results to text file here

            If Not dr.IsClosed Then dr.Close()
            GBAScn.Close()
            RaiseEvent eQueryComplete(sDateFrom, sDateTo)

        Catch ex As Exception
            If Not dr.IsClosed Then dr.Close()
            GBAScn.Close()
            RaiseEvent eQueryComplete("Error", ex.Message)

        End Try
    End Sub
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11874266
Yeah, it still has the same results. (already tried that)
When in debug mode I cant step through eQueryComplete and I see that sdateto has a value of the error text, and the code that sets the textbox text gets run but when checking the text property immediatly after the code executes reveals that the text property is still "".
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11874383
Just for grits and shins...why don't you try using a seperate event for errors and see what happens...

Public Class VIPList
    Inherits System.Windows.Forms.Form
    ...
    Private WithEvents oBGProcess As BackgroundQuery
    Private tMain As Thread

    'button click starts thread

    Private Sub QueryDone(ByVal sDateFrom As String, ByVal sDateTo As String) Handles oBGProcess.eQueryComplete
        ....
        SaveSetting("CSRT", User_ID, "VIP Estimated", tTimeStarted & "~" & Now)
        ProgressBar1.Value = ProgressBar1.Maximum

        Dim proc As Process
        If File.Exists(Application.StartupPath & "\" & sDateFrom & "_" & sDateTo & ".csv") Then _
        proc.Start(Application.StartupPath & "\" & sDateFrom & "_" & sDateTo & ".csv")
    End Sub

    Private Sub QueryError(ByVal sMsg As String) Handles oBGProcess.eQueryError
        txtError.Visible = True
        txtError.Text = "ERROR: " & vbCrLf & sMsg
    End Sub
End Class

Public Class BackgroundQuery
    Public Event eQueryComplete(ByVal sDateFrom As String, ByVal sDateTo As String)
    Public Event eQueryError(ByVal sMsg As String)
    ....
    Public Sub MainQuery()
        Dim GBAScm As New OleDb.OleDbCommand
        Dim GBASdr As OleDb.OleDbDataReader

        'Go do it
        Try
            GBAScn.Open()
            GBAScm.Connection = GBAScn

            'Query Here

            'Write Query Results to text file here
            If Not dr.IsClosed Then dr.Close()
            GBAScn.Close()
            RaiseEvent eQueryComplete(sDateFrom, sDateTo)

        Catch ex As Exception
            If Not dr.IsClosed Then dr.Close()
            GBAScn.Close()
            RaiseEvent eQueryError(ex.Message)

        End Try
    End Sub
End Class
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11875096
When I do that, I cant step through the code and the textbox takes the value of the passed string but as soon at the thread finishes the textbox goes back to ""
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11875448
Sorry, skip last post

When I do that, and when I step through the code the textbox takes the value of the passed string but as soon at the thread finishes the textbox goes back to ""
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11875648
It sound to me like the thread and events are working just fine.  The problem most likely lies somewhere else where you are resetting the textbox and that sub/function is being called when you are not expecting it to.

Is it possible to a more complete picture of the code?

Idle_mind
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11883624
Imports System.IO
Imports System.Threading

Public Class VIPList
    Inherits System.Windows.Forms.Form



    'THREADING
    Private WithEvents oBGProcess As BackgroundQuery  'Opens a new process for running the refresh thread
    Private tMain As Thread                           'main thread used to capture data from db

    Dim tTimeStarted As DateTime
    Dim dMiliSecondCounter As Decimal
    Dim sTemp As String

    Private Sub VIPList_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        txtCIUserName.Text = GetSetting("CSRT", User_ID, "Import Username", "")
        txtCIPassword.Focus()
        GetEstimatedTime()
        SplashForm.Hide()
    End Sub
    Private Sub btnCIImport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCIImport.Click

        If txtCIPassword.Text = "" Then MessageBox.Show("You must enter a password first", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) : txtCIPassword.Focus() : Exit Sub

        'Prep Work
        GetEstimatedTime()

        btnCIImport.Enabled = False
        btnCIImport.Text = "Searching Please Wait"
        tTimeStarted = Now
        tmrCounter.Enabled = True
        picbox.Visible = True
        Me.Cursor = Windows.Forms.Cursors.WaitCursor

        Application.DoEvents()

        Dim sDateFrom As String = dtpFrom.Value.Year & "-" & dtpFrom.Value.Month & "-" & dtpFrom.Value.Day
        Dim sDateTo As String = dtpTo.Value.Year & "-" & dtpTo.Value.Month & "-" & dtpTo.Value.Day

        Application.DoEvents()

        'Start Search Thread
        oBGProcess = New BackgroundQuery
        If Not tMain Is Nothing Then If tMain.ThreadState <> ThreadState.Stopped Then Exit Sub
        tMain = New Thread(AddressOf oBGProcess.MainQuery)
        Dim GBAScn As New OleDb.OleDbConnection
        Init_GBAS_Database_Connection(GBAScn, txtCIUserName.Text, txtCIPassword.Text)
        oBGProcess.GBAScn = GBAScn
        oBGProcess.sDateFrom = sDateFrom
        oBGProcess.sDateTo = sDateTo
        oBGProcess.sSearchFor = txtCISearchString.Text
        tMain.Start()
    End Sub
    Private Sub GetEstimatedTime()
        Dim sEstimated As String = GetSetting("CSRT", User_ID, "VIP Estimated", "15:00:00")

        If sEstimated = "15:00:00" Then
            lblEstimated2.Text = sEstimated
            ProgressBar1.Maximum = 900
        Else
            Dim sStart As String = Strings.Left(sEstimated, InStr(sEstimated, "~") - 1)
            Dim sEnd As String = Strings.Right(sEstimated, Len(sEstimated) - InStr(sEstimated, "~"))
            If CDate(sEnd).Subtract(CDate(sStart)).Minutes < 10 Then
                lblEstimated2.Text = "0" & CDate(sEnd).AddSeconds(30).Subtract(CDate(sStart)).Minutes & ":"
            Else
                lblEstimated2.Text = CDate(sEnd).AddSeconds(30).Subtract(CDate(sStart)).Minutes & ":"
            End If
            If CDate(sEnd).AddSeconds(30).Subtract(CDate(sStart)).Seconds < 10 Then
                lblEstimated2.Text += "0" & CDate(sEnd).AddSeconds(30).Subtract(CDate(sStart)).Seconds & ":00"
            Else
                lblEstimated2.Text += CDate(sEnd).AddSeconds(30).Subtract(CDate(sStart)).Seconds & ":00"
            End If
            ProgressBar1.Maximum = (CDate(sEnd).AddSeconds(30).Subtract(CDate(sStart)).Minutes * 60) + CDate(sEnd).AddSeconds(30).Subtract(CDate(sStart)).Seconds
        End If

    End Sub
    Private Sub QueryDone(ByVal sDateFrom As String, ByVal sDateTo As String) Handles oBGProcess.eQueryComplete
        btnCIImport.Enabled = True
        btnCIImport.Text = "Get List"
        picbox.Visible = False
        tmrCounter.Enabled = False
        Me.Cursor = Windows.Forms.Cursors.Arrow

        If sDateFrom = "Error" Then
            txtError.Visible = True
            txtError.Text = "ERROR: " & vbCrLf & sDateTo
            MessageBox.Show(sDateTo)
            'GenericError("VIP List", "Main Query", sDateTo)
        Else
            SaveSetting("CSRT", User_ID, "VIP Estimated", tTimeStarted & "~" & Now)
            ProgressBar1.Value = ProgressBar1.Maximum

            Dim proc As Process
            If File.Exists(Application.StartupPath & "\" & sDateFrom & "_" & sDateTo & ".csv") Then _
            proc.Start(Application.StartupPath & "\" & sDateFrom & "_" & sDateTo & ".csv")
        End If
        Application.DoEvents()
        Me.Activate()
    End Sub
    Private Sub Queryerror(ByVal sError As String) Handles oBGProcess.eQueryError
        txtError.Visible = True
        txtError.Text = "ERROR: " & vbCrLf & sError
    End Sub

    Private Sub tmrCounter_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrCounter.Tick
        dMiliSecondCounter += 1
        If dMiliSecondCounter = 100 Then dMiliSecondCounter = 0
        Dim sMinutes As String = Now.Subtract(tTimeStarted).Minutes.ToString
        Dim sSeconds As String = Now.Subtract(tTimeStarted).Seconds
        Dim sMiliSeconds As String = dMiliSecondCounter
        If CInt(sMinutes) < 10 Then sMinutes = "0" & sMinutes
        If CInt(sSeconds) < 10 Then sSeconds = "0" & sSeconds
        If CInt(sMiliSeconds) < 10 Then sMiliSeconds = "0" & sMiliSeconds

        lblElapsed2.Text = sMinutes & ":" & sSeconds & ":" & sMiliSeconds

        If (Now.Subtract(tTimeStarted).Seconds + Now.Subtract(tTimeStarted).Minutes * 60) < ProgressBar1.Maximum Then _
            ProgressBar1.Value = (Now.Subtract(tTimeStarted).Seconds + Now.Subtract(tTimeStarted).Minutes * 60)
    End Sub
End Class

Public Class BackgroundQuery

    Public Event eQueryComplete(ByVal sDateFrom As String, ByVal sDateTo As String)
    Public Event eQueryError(ByVal sError As String)

    Public GBAScn As New OleDb.OleDbConnection
    Public sDateFrom, sDateTo As String
    Public sSearchFor As String

    Public Sub MainQuery()
        Dim GBAScm As New OleDb.OleDbCommand
        Dim GBASdr As OleDb.OleDbDataReader

        Const sQuote As String = """"

        'Go do it
        Try
            GBAScn.Open()
            GBAScm.Connection = GBAScn

            GBAScm.CommandText = "SELECT CLMFIL_FILE.CASE_NUM, CLMFIL_FILE.CERT_NUM, CLMFIL_FILE.CLMT_NUM, DTLFIL_FILE.CLAIM_NUM, CLMFIL_FILE.LAST_NAME, CLMFIL_FILE.FIRST_NAME, DTLFIL_FILE.STATUS, DTLFIL_FILE.SYS_YYYYMMDD " & _
                                 "FROM CLMFIL_FILE, DTLFIL_FILE " & _
                                 "WHERE CLMFIL_FILE.MESSAGE_25 LIKE '%" & sSearchFor & "%' " & _
                                 "AND DTLFIL_FILE.CASE_NUM = CLMFIL_FILE.CASE_NUM " & _
                                 "AND DTLFIL_FILE.CERT_NUM = CLMFIL_FILE.CERT_NUM " & _
                                 "AND DTLFIL_FILE.CLMT_NUM = CLMFIL_FILE.CLMT_NUM " & _
                                 "AND DTLFIL_FILE.SYS_YYYYMMDD >= '" & sDateFrom & "' " & _
                                 "AND DTLFIL_FILE.SYS_YYYYMMDD <= '" & sDateTo & "' " & _
                                 "AND CLMFIL_FILE.STATUS='A' " & _
                                 "ORDER BY DTLFIL_FILE.SYS_YYYYMMDD ASC"
            GBASdr = GBAScm.ExecuteReader

            Dim sw As StreamWriter
            Dim F As File
            sw = F.CreateText(Application.StartupPath & "\" & sDateFrom & "_" & sDateTo & ".csv")
            sw.WriteLine(sQuote & "VIP Claim list" & sQuote)
            sw.WriteLine(sQuote & sDateFrom & " to " & sDateTo & sQuote)
            sw.WriteLine("""CASE"",""CERT"",""CLAIMANT"",""CLAIM"",""LAST NAME"",""FIRST NAME"",""STATUS"",""LAST ACTION DATE""")
            While GBASdr.Read
                sw.WriteLine(sQuote & GBASdr(0) & sQuote & "," & _
                             sQuote & GBASdr(1) & sQuote & "," & _
                             sQuote & GBASdr(2) & sQuote & "," & _
                             sQuote & GBASdr(3) & sQuote & "," & _
                             sQuote & GBASdr(4) & sQuote & "," & _
                             sQuote & GBASdr(5) & sQuote & "," & _
                             sQuote & GBASdr(6) & sQuote & "," & _
                             sQuote & GBASdr(7) & sQuote)
            End While
            sw.Close()
            RaiseEvent eQueryComplete(sDateFrom, sDateTo)
        Catch ex As Exception
            'RaiseEvent eQueryComplete("Error", ex.Message)
            RaiseEvent eQueryError(ex.Message)
        Finally
            If Not dr.IsClosed Then dr.Close()
            GBAScn.Close()
        End Try
    End Sub
End Class
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11888929
I can't find anything wrong with your code.

=(
Idle_Mind
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11889229
Comming from you I will take that as a compliment... LoL

Is there something in .net that wont allow one thread to change the properties of an object in another thread? I know that even though the QueryDone/QueryError code is located in the class of "VIPList" it is actually executed under the tMain thread.

Thats all I can come up with though.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11889287
I will make a test app to test the theory.

Idle_Mind
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11889525
>> Is there something in .net that wont allow one thread to change the properties of an object in another thread?

Here is an app that is doing essentially the same thing as yours.  The class has two threads that raise different events.  The events are trapped by the main form and the label and progressbar are changed as a result.

Idle_Mind

Imports System.Threading
Public Class Class1

    Public Event posChange(ByVal bc As Color, ByVal deltaValue As Byte, ByVal msg As String)
    Public Event negChange(ByVal bc As Color, ByVal deltaValue As Byte, ByVal msg As String)

    Private posThread As Thread = New Thread(AddressOf Me.positiveProgess)
    Private negThread As Thread = New Thread(AddressOf Me.negativeProgress)

    Public Sub New()
        posThread.Start()
        negThread.Start()
    End Sub

    Private Sub positiveProgess()
        While True
            If DateTime.Now.Second Mod 2 = 0 Then
                RaiseEvent posChange(Color.Green, 1, "Positive")
            End If
            Thread.Sleep(50)
            Application.DoEvents()
        End While
    End Sub

    Private Sub negativeProgress()
        While True
            If DateTime.Now.Second Mod 2 <> 0 Then
                RaiseEvent negChange(Color.Red, 1, "Negative")
            End If
            Thread.Sleep(50)
            Application.DoEvents()
        End While
    End Sub

    Public Sub Dispose()
        posThread.Abort()
        negThread.Abort()
    End Sub

    Protected Overrides Sub Finalize()
        Dispose()
        MyBase.Finalize()
    End Sub

End Class


Imports System.Threading

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    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.
    Friend WithEvents ProgressBar1 As System.Windows.Forms.ProgressBar
    Friend WithEvents Label1 As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.ProgressBar1 = New System.Windows.Forms.ProgressBar
        Me.Label1 = New System.Windows.Forms.Label
        Me.SuspendLayout()
        '
        'ProgressBar1
        '
        Me.ProgressBar1.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.ProgressBar1.Location = New System.Drawing.Point(8, 40)
        Me.ProgressBar1.Name = "ProgressBar1"
        Me.ProgressBar1.Size = New System.Drawing.Size(330, 18)
        Me.ProgressBar1.TabIndex = 3
        Me.ProgressBar1.Value = 50
        '
        'Label1
        '
        Me.Label1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.Label1.BackColor = System.Drawing.Color.Black
        Me.Label1.ForeColor = System.Drawing.Color.White
        Me.Label1.Location = New System.Drawing.Point(8, 8)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(330, 24)
        Me.Label1.TabIndex = 5
        Me.Label1.Text = "Label1"
        Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(346, 64)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.ProgressBar1)
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
        Me.Name = "Form1"
        Me.Text = "Threads in a Class Raising Events"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private WithEvents c As Class1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        c = New Class1
    End Sub

    Private Sub c_posChange(ByVal bc As System.Drawing.Color, ByVal deltaValue As Byte, ByVal msg As String) Handles c.posChange
        Label1.BackColor = bc
        Label1.Text = msg
        If ProgressBar1.Value + deltaValue > ProgressBar1.Maximum Then
            ProgressBar1.Value = ProgressBar1.Maximum
        Else
            ProgressBar1.Value = ProgressBar1.Value + deltaValue
        End If
    End Sub

    Private Sub c_negChange(ByVal bc As System.Drawing.Color, ByVal deltaValue As Byte, ByVal msg As String) Handles c.negChange
        Label1.BackColor = bc
        Label1.Text = msg
        If ProgressBar1.Value - deltaValue < 0 Then
            ProgressBar1.Value = 0
        Else
            ProgressBar1.Value = ProgressBar1.Value - deltaValue
        End If
    End Sub

    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        c.Dispose()
        c = Nothing
    End Sub

End Class
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11893708
So I changed a few things.
If I fire a message box after the error code like this

            txtError.Visible = True
            txtError.Text = "ERROR: " & vbCrLf & sDateTo
            MessageBox.Show(sDateTo)

Then before I click the ok button on the messagebox I can see the textbox, and it has text, and as soon as I click to ok button e.g. the thread ends it revert bact to its original state.
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11893746
if the textbox is visible before the thread is run, then the textbox remains visible and the text in the textbox stays after the thread has exited.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11893963
How about if the textbox is initially not visible but you use this code?

        txtError.Visible = True
        txtError.Text = "ERROR: " & vbCrLf & sDateTo
        txterror.Refresh()
        Application.DoEvents()
        'MessageBox.Show(sDateTo)

By the way, the test app I wrote also behaves differently if I make the label initially not visible and then toggle its visibility from the event handler.

Idle_Mind
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 250 total points
ID: 11894120
After more fiddling with my test app I found more interesting behaviour...

If the visibility of the label is false in the IDE, and the first time the visbility is toggled to true is from within the event fired by the threads, then the app does not behave as expected.

If the visiblity of the label is true in the IDE but I immediately toggle it to false in the form load event (before the threads start firing events), then when the visibility is again toggled to true from the event fired by the thread, the app works correctly.

So try making the initial visibility state or your txtError textbox True, but hide it in your form load event and I think it will work as expected with just:

    txtError.Visible = True
    txtError.Text = "ERROR: " & vbCrLf & sDateTo

Idle_Mind
0
 
LVL 3

Author Comment

by:gbarcalow
ID: 11894288
!!Cheering!!, Im not insane.

That sounds exactly like what I have been experiencing.

I changed its initial state to visible, and then in the load even made it invisible and everything now works as expected.

Sounds like one more thing to thank MS for.

Thanks for all your help
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 11894366
Definitely sounds like a bug.

I think that when the initial state of a control is false in the IDE, it does not actually get loaded with the form.  

When we toggle its visibility for the first time, then the control gets created and added to the forms control collection.

Then, something *waves hands in air magically* about the thread interactions prevents the newly created control from being modified before the thread ends.

I agree with your sentiment!

Thanks Micro$oft...

Idle_Mind
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

758 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now