Visual Studio 2013: Cannot update textbox with event handler - vb.net

I am building an application using one of our vendors interfaces, which is required to keep a status message box updated.
I have some events which I have handled for testing using a Message box, but now I come to pass these messages to the display box I get nothing.
Public Shared Sub PageAirHandler(ChannelNum As Integer, Index As Integer, ChannelType As CLARITYCOMLib.ChannelType, PageName As String) Handles Status1.AirStatusChanged
MessageBox.Show(PageName)
ControlPanel.AirStatusBox.Text = PageName
End Sub
The messagebox dutifully displays the PageName string, but the textbox does nothing... even if I replace the PageName String variable with "test"
ControlPanel.AirStatusBox.Text = "test"
I get no activity, no errors, nada.
I have googled around, but every example I can find seems to show the same code.
I have recreated the textbox, tried buttons, labels and other objects with the same result.
Setting up a button click handler to update any of these works as expected.
Apologies if this is a noob blunder, but it's driving me nuts!

Using dlg As New Form2
dlg.ShowDialog()
End Using
Things like:
Form2.Show()
Form2.Show(Me)
Form2.ShowDialog()
Form2.ShowDialog(Me)
SHOUL BE AVOIDED but are possible, because Vb.net creates an implicit instance.
But the problem is, this instance gets killed if
the call has be done.
There you can see that a class instance of a project does not interact correctly
in some cases.
As Hans Passant said, your call to set the textbox text
targets the wrong instance.
Invoking to user controls is also possible with:
Me.invoke(sub()
TextBox1.Text = "Blabla"
End sub)

Related

Label Text not updating even when using Refresh, Invalidate, and DoEvents

My code is designed to be a control system for a 2-axis motion system. I have 2 drives that each output a count of their steps. I can read the device, update a property, and update the text field of a label. However, it does not update the form. When I use a message box, I can display the text value being correct, but nothing updates the label.
I'm happy to try any suggestions, but I've been fighting this for about 16 hours and I'm at my wits end - as evidenced by the clear overkill/terrible coding that is shown in the code. I can't understand why it's not updating.
Additionally, a manual button with all versions seen below to refresh a form doesn't update the control.
Direction, recommendations?
Private Sub PositionChanged(ByVal sender As Object, ByVal e As EventArgs)
If TraverseController.InvokeRequired Then
TraverseController.Invoke(
New EventHandler(Of EventArgs)(AddressOf PositionChanged), sender, e)
Return
End If
'RaiseEvent PropertyChanged(TraverseController, New System.ComponentModel.PropertyChangedEventArgs("Position"))
MessageBox.Show(TraverseController.lblLinearDrivePosDisp.Text)
TraverseController.lblLinearDrivePosDisp.Text = CStr(_position)
Application.DoEvents()
TraverseController.lblLinearDrivePosDisp.ResetBindings()
TraverseController.GBDrivePositionDisp.Refresh()
TraverseController.lblLinearDrivePosDisp.Refresh()
TraverseController.Refresh()
TraverseController.Invalidate()
TraverseController.Update()
Application.DoEvents()
MessageBox.Show(TraverseController.lblLinearDrivePosDisp.Text)
End Sub
Assumption: TraverseController is form's class name.
This looks like a VB default form instance issue. It is apparent that you are trying to properly marshal control interaction back to the UI thread by using checking TraverseController.InvokeRequired. However, due to the way these default instance are created, TraverseController.InvokeRequired is creating a new instance of TraverseController on the secondary thread and all subsequent code is modifying that instance and not the one created on the UI thread.
One way to deal with this is to pass a synchronizing control instance to the class where PositionChanged changed method is defined and check that control's InvokeRequired method instead of TraverseController.InvokeRequired. If the containing class is itself a UI control, then use that class instance (Me.InvokeRequired).

Put A textbox value in a Label from another form

I have Two Forms
In The First Form I Have A Textbox Called TB1 An A String Called S1
In The Second Form I Have A Label Called L1
I Declared them publicly in a module
Module M1
Public L1 As New Label
Public TB1 As new Textbox
Public S1 As new String
End Module
/../
'in the First form
S1=TextBox1.text
'in the second form
L1.text=S1
But I Get this error "System.NullReferenceException" on the first Label L1
Any ideas why i'm getting this error
Try something like this:
On Form1 in the event calling Form2, Add:
Form2.L1.Text = TextBox1.text
Form2.Show()
You can't put them in a module like that; nothing will see them.
In addition, there's no way to see how this code is flowing.
To do a simple exercise:
Draw first form - form1 with Textbox1 on it.
Make the first form startup form (it will be by default in new winforms project)
Draw 2nd form - form2 with Label1 on it.
Put a button on the first form
Double click the button
In the handler put this code:
Sub Button1_Click (etc...
dim Form2Instance as new Form2
Form2Instance.Label1.Caption = Textbox1.text
Form2Instance.ShowDialog
End Sub
You can put a textbox on form2 and read the results in form1 the same way.
You can tell if the user OK'd (not canceled) form2 like this:
if Form2Instance.ShowDialog() = DialogResults.OK then
' only do this code if they HIT OK
I suggest maybe hitting youtube or pluralsite and watching a 'winforms for beginners' video, if such a thing exists. There are a lot of traps and pitfalls that you will run into hacking away on your own, that will be explained to before hand if you learn the basics. This is especially true if you've only done web programming or are just learning programming.

How to set a listview FocusedItem programatically

How can I set the FocusedItem property programatically?
I've tried this so far with no success:
If lvw.FocusedItem Is Nothing Then
If lvw.Items.Count > 0 Then
lvw.Focus()
lvw.HideSelection = False
lvw.Items(0).Selected = True
lvw.Items(0).Focused = True
lvw.FocusedItem = lvw.Items(0)
lvw.Select()
End If
End If
btw the form where the listview is has not called the ShowDialog method yet.
Can this be the reason for this not to work?
You have to understand that each control on the Form and the Form itself is a window and for the window to have focus it must first be created and assigned a handle.
For a basic description of this, I refer you to: All About Handles in Windows Forms The following excerpts are from the referenced article.
What is a Handle?
A handle (HWND) is the return value from CreateWindowEx which the Windows Operating System uses to identify a window. A "window" in win32 is a much broader concept than you may think - each individual button, combobox, listbox etc comprises a window. (For more information see About Window Classes ) NOTE: there are other things known as "Handles" in the Framework - e.g. GDI Handles from a Bitmap or Handles to Device Contexts (HDCs) - this article discusses HWNDs only.
...
When does a Control create its handle? (When does a control call CreateWindowEx?)
A control tries as much as possible to defer creating its handle. This is because setting properties forces chatty interop between the CLR and user32.
Typically the handles for all the controls are created before the
Form.Load event is called. Handles can also be created if the "Handle"
property is called and the handle has not yet been created, or
CreateControl() is called.
So a window's handle is not immediately created when you instantiate a control. However, you can force a control to create its handle by referencing its Handle property.
So if you first get the ListView to create its handle, then when you set those properties that you wanted.
Dim f2 As New Form2
' you do not need this condition, it is here only for demonstration purposes
' so that you can step through the code in the debugger and observe the
' code execution.
If Not f2.ListView1.IsHandleCreated Then
' retrieval of the Handle will cause a handle to be created
' if it has not yet been created
' if you delete the If-Then block, you will need to retain the
' following statement
Dim h As IntPtr = f2.ListView1.Handle
End If
f2.ListView1.FocusedItem = f2.ListView1.Items(2)
f2.ListView1.Items(2).Selected = True
f2.ListView1.Items(2).Focused = True
f2.ActiveControl = f2.ListView1
f2.ShowDialog()
As others have commented, your code should work as written. If all you need is to programmatically access the focused item in your code, you shouldn't be experiencing any difficulties. (If you are, please describe them.)
If you are looking for a visual effect (the row being highlighted), my guess is that your code is in another control's event and the focus is being set back to that control automatically the instant after your code runs. More than likely your code needs to be where it is and trying to move it elsewhere to prevent this issue would be a waste of time.
However, there are other ways to set a row apart visually. When a list view isn't likely to stay focused, my preferred method is to distinguish the selected item with a different fore/back color. (You can use the focused item if you prefer, but I find the selected item more useful. Your call.)
Here is an example which visually highlights the selected row, regardless of focus:
Private Sub lvw_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lvw.SelectedIndexChanged
If lvw.Items Is Nothing Then Exit Sub
For Each lvi As ListViewItem In lvw.Items
If lvi.Selected = True Then
lvi.ForeColor = Color.DarkGray
lvi.BackColor = Color.LightCyan
Else
lvi.ForeColor = Color.Black
lvi.BackColor = Color.White
End If
Next
End Sub
EDIT:
In response to the added information that this form is being displayed using ShowDialog, yes, that is likely the source of your problem.
ShowDialog creates a new instance of the form. Therefore, if you have set any properties of a form or its controls, and later call ShowDialog to display that form, the form displayed is a new copy of the original form and will not reflect the changes you made programatically.
Imagine you sit down at a computer where a blank Word document is already open. You type something in it and then open a new document. The text you typed in the first document is not copied to the second. I think this is the root of your troubles here.

Catch a value from form1 to form2 in vb [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
In VB, I create 2 forms in 1 project. In form1, I put 3 buttons with different value. In form2, I only put 1 textbox with no value.
My question is, how if I press one of the button in form1, the form2 is automatically opened and the value from the button that I press automatically added to the form2 textbox?
Add following code into your button handler. You can double click button and add the code into event handler which is automatically created:
'Here we are creating actual object and passing string into it constructor method
Dim instanceOfForm2 = new Form2("String value from Form1!")
instanceOfForm2.Show() ' Showing form
In Form2 we need to tweak our constructor to accept one parameter:
Public Sub New(someValue as String)
InitializeComponents() 'This is always first row in form constructor
TextBox1.Text = someValue 'And put that text into textbox...
End Sub
In VB6 you can do all the stuff that lardymonkey has in place, but you don't have to. The most concise way to do what you want is this. First, make your three command buttons in Form1 into a control array. To do this, give them all the same name (I'll use "cmdMyButtons" in my example), and set their index properties to 0, 1, and 2. Then do this in Form1's code window:
Option Explicit
Dim ButtonText(2) As String
Public Sub Form_Load()
ButtonText(0) = "First Button Text"
ButtonText(1) = "Second Button Text"
ButtonText(2) = "Third Button Text"
End Sub
Public Sub cmdMyButtons_Click(Index As Integer)
With Form2
.txtMyTextBox.Text = ButtonText(Index)
.Show vbModal
End With
End Sub
Now, I like lardymonkey's idea of showing modally, so I put it in here as well. However, several things in his code sample aren't intrinsically necessary to do what you want, and create overhead, so I pulled them out:
You don't need to make a property; you can just set the text
directly as I have here.
You don't need to create a form variable; you can just reference the form directly as I have here.
You don't have to load the form explicitly; the form gets
automatically loaded as soon as you set the variable (by the way,
the Show method also automatically loads the form, too--you only use
Load when you want to have the form loaded into memory before you do
anything to it).
If you close the modal form it will be
automatically unloaded. However, unloading a form doesn't set any
object variables referencing it to nothing. Therefore, frmDetail
will not be Nothing when you check it, you will unload a form that
isn't loaded. While this doesn't throw an error (the statement is ignored), I wouldn't do it anyway. So, you don't
need any of the "make sure the form is destroyed" code.
And now, for a short lecture on the whole business of always explicitly destroying object variables:
There is a longstanding argument about whether you need to explicitly set all your local object variables to Nothing before exiting a subroutine in VB6. I don't agree with this at all; VB takes care of this automatically when the variables go out of scope. As far as I can see, the reason that people believe that they have to do this is that the scope finalizer doesn't collect garbage in any particular order, and sometimes two interacting COM objects need to be destroyed in a particular order due to poor coupling architecture. In such a case, you do indeed need to clear the objects in the correct order to work around intermittent bugs, so the myth developed that VB's garbage collection is buggy and needs to be circumvented by always manually destroying object variables.
Frankly, the idea that a programmer is going to always do this and never forget is naive. So I persist in disagreeing with it; the developers of VB6 put a lot more thought and effort into developing the scope finalizer than any programmer is going to put into circumventing it.
Without knowing the specific version of the software you are using we cant answer, we can answer it if you provide the correct version
In .net it's a simple as creating the form then passing the value over.
Friend objForm2 as New Form2
Private Sub button1_Click(ByVal sender As System.Object, ByVal e as System.EventArgs) Handles button1.Click
objForm2 = new Form2()
TextBox1.Text = value
End Sub
This would be a way of doing it in VB6. I've left the error handling up to you.
I've made the assumption that the name of the text box is txtOutput on form2.
In Form2 add the following:
Option Explicit
Public Property Let OutputText(ByVal strOut As String)
txtOutput.Text = strOut
End Property
In Form1 add the following:
Option Explicit
Private Sub Command1_Click()
DisplayForm "1"
End Sub
Private Sub Command2_Click()
DisplayForm "2"
End Sub
Private Sub Command3_Click()
DisplayForm "3"
End Sub
Private Sub DisplayForm(ByVal strValue As String)
'Declare the variables
Dim frmDetail As Form2
'Create the form
Set frmDetail = New Form2
'Load the form and display it modal
Load frmDetail
frmDetail.OutputText = strValue
frmDetail.Show vbModal, Me
'Make sure the form is destoryed
If Not frmDetail Is Nothing Then
Unload frmDetail
Set frmDetail = Nothing
End If
End Sub
Make sure you comment the code and if you need some error handling then add it. If you need help with the VB6 functions you can find it here MSDN VB6 Reference

VBA Listbox becomes unresponsive after first use

I have a VBA (Excel 2010) system which involves selecting an item from a listbox and then displaying it in another form. Here is a very simplified version of what happens.
' Part of frmForm1 code module
sub lstListbox_Click
dim MyEvent as string
dim i as integer
i=me.lstListbox.listindex
MyEvent=me.lstlistbox.list(i)
' Now show the item in the second form
Load frmForm2
me.hide
ThisWorkbook.LoadDataIntoForm2 (frmForm2, MyEvent)
frmForm2.show
unload frmForm2
me.show
end sub
The listbox accepts the click, and first the event (the event handler is giver above). Key parts of the event handler are:
Load the second form (to display the detail data)
Pass the second form as a UserForm parameter to a procedure (LoadDataIntoForm2)
Hide the host form (frmForm1) and show the second form (frmForm2)
When the second form processes an Exit click, the code looks like this:
' Part of frmForm2 code module
sub cmdExit_Click
me.hide
end sub
The first time round it works fine - but when I return to frmForm1 (in the tail end of the lstListBox_Click procedure), even though the rest of the form is operative, the listbox remains stubbornly unresponsive.
I've managed to abstract this down to a little demo system if that would help - the same behavior is seen there. (It's regular .xls file, but that seems not to be easily acceptable as an upload)
Has anyone seen this before? And does anyone have any ideas how I might get this to work the way I want it to?
Thanks,
Tony
The default for the .Show method is to make the form modal. Explicitly set it to modeless:
Sub lstListbox_Click
...
Me.Show vbModeless
End Sub