Ваша проблема связана с тем, что вы используете экземпляр по умолчанию из newform
. В VB.NET экземпляры форм по умолчанию - это функция, которая позволяет вам получить доступ к форме через имя типа, не создавая ее вручную.
Другими словами, это позволяет вам сделать это:
newform.Show()
newform.TextBox1.Text = "Something"
... вместо того, чтобы делать это правильным образом, а именно:
Dim myNewForm As New newform
myNewForm.Show()
myNewForm.TextBox1.Text = "Something"
Выше мы создаем новый экземпляр newform
с именем myNewForm
. Это необходимо для возможности использования большинства объектов в каркасе (включая формы). Однако VB.NET упрощает это поведение, предлагая создать экземпляр для вас, что и происходит в моем первом примере.
Проблема с этими экземплярами по умолчанию заключается в том, что они специфичны для каждого потока, то есть для каждого потока создается новый экземпляр *1021*, в котором вы используете это поведение.
Таким образом, форма, на которую вы ссылаетесь, когда вы делаете:
newform.Show()
... это не та форма, на которую вы ссылаетесь в своей теме, потому что для нее был создан новый экземпляр в этой теме :
'This is not the same "newform" as above!
SetText(newform.TextBox1, Difference.ToString)
Решением этой проблемы, конечно же, является создание экземпляра самостоятельно, что позволяет вам полностью контролировать происходящее:
Dim newFrm As New newform
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
newFrm.Show()
End Sub
...your code...
Sub Test()
...your code...
SetText(newFrm.TextBox1, Difference.ToString)
...even more of your code...
End Sub
В качестве дополнительной заметки вы можете удалить свои звонки на newform.Refresh()
и Txtbox.Update()
. Это просто приводит к ненужным накладным расходам, заставляя форму и текстовые поля перерисовывать себя, что уже сделано, когда вы изменяете любое из их свойств, которые влияют на их содержимое / дизайн (таким образом, вы фактически заставляете их перерисовывать себя дважды).
Кроме того, если вы хотите сделать вызов в потоке пользовательского интерфейса проще и используете Visual Studio / Visual Basic 2010 или новее , вы можете переключиться к использованию лямбда-выражений вместо обычных делегатов. Они намного проще в использовании и позволяют создавать целые встроенные методы, которые можно вызывать в потоке пользовательского интерфейса.
Для этой цели я написал метод расширения под названием InvokeIfRequired()
, который позволяет вам вызывать любой метод / функцию в потоке пользовательского интерфейса, проверяя InvokeRequired
для вас. Это похоже на то, что у вас есть сейчас, только оно работает для любого элемента управления (не только для текстовых полей) и с лямбда-выражениями, позволяет запускать любой код, который вы хотите в пользовательском интерфейсе.
Вы можете использовать его, добавив модуль в ваш проект (Add New Item... > Module
) и присвоив ему имя Extensions
. Затем поместите этот код внутри него:
Imports System.Runtime.CompilerServices
Public Module Extensions
''' <summary>
''' Invokes the specified method on the calling control's thread (if necessary, otherwise on the current thread).
''' </summary>
''' <param name="Control">The control which's thread to invoke the method at.</param>
''' <param name="Method">The method to invoke.</param>
''' <param name="Parameters">The parameters to pass to the method (optional).</param>
''' <remarks></remarks>
<Extension()> _
Public Function InvokeIfRequired(ByVal Control As Control, ByVal Method As [Delegate], ByVal ParamArray Parameters As Object()) As Object
If Parameters IsNot Nothing AndAlso _
Parameters.Length = 0 Then Parameters = Nothing
If Control.InvokeRequired = True Then
Return Control.Invoke(Method, Parameters)
Else
Return Method.DynamicInvoke(Parameters)
End If
End Function
End Module
Это позволяет вам вызвать одну строку кода, выполнив:
Me.InvokeIfRequired(Sub() Me.TextBox1.Text = Difference.ToString())
Или вызвать целый блок кода, выполнив:
Me.InvokeIfRequired(Sub()
Me.TextBox1.Text = Difference.ToString()
newFrm.TextBox1.Text = Difference.ToString()
Me.BackColor = Color.Red 'Just an example of what you can do.
End Sub)