I am upgrading a program that I wrote in VB6 to VB2005 and am having trouble with textboxes.
In the VB6 version, I used an array of textboxes to display and order text on screen according to it's priority. This was done in a module. The VB6 program takes a new message, checks it's priority (assigns the texbox color according to priority) and then adds it into the array according to the textbox color and arrival sequence of both itself and the existing array members.
In the 2005 version data is processed by a module and passed to the form (because I can't process the text boxes in the module). The form then needs to display the data on the form in time order (newest at the top) and priority order (highest priority at the top). There are several priorities, so they need to be ordered at the top firstly by priority and then by time within there own priority (so if there are 2 highest priority messages, the newest is at the top). Once the screen is full (10 or 12 messages) the oldest ones at the bottom can just fall off as new ones arrive at the top.
Any help will be greatly appreciated.

TextBox array
Dino Ablakovic
Just to clarify, it falls over on the "f.show" line.
Thanks.
Jon L
This error message is indicating that you havent instanced and attempted to use it.
Normally when you create an Object you will use something like
Dim x as New class1
or
Dim x as class1
x = new class1
What this is doing is creating an instance object of type class1. You could then use methods on the object x as you have created an instance.
If you do something like
Dim x as Class1
and try and use the methods on it you will get "Object reference not set to an instance of an object." This is because x is merely a reference to an object - not an instance of an object. Its the New keyword which creates the instance.
So I would guess that you if you put a breakpoint on this line and look at the variable f you will probably see it has a value of nothing and that you havent created an instance object called f. ie. you are missing a new statement somewhere in your code.
Hope that provides some clues to what this message means.
hamidhsn
Check the UpdateMessage code...
In the form referenced by 'f' there should be a subroutine named UpdateMessage. Set a breakpoint on this subroutine and then run the application. First, see if the debugger steps into UpdateMessage when the f.Invoke() line of code is executed. If so, step through the UpdateMessage subroutine and see if you get the 'not set' exception somewhere in this routine.
Imti
Sorry for the delay in replying.
I have played around with the code a bit now and with your code in place:
if f is nothing then
msgbox("not set")
else
f.show
end if
I do not get the "not set" message but it falls over on the f.show with the error "Cross-thread operation not valid". I checked the f variable before the code stopped, it does hold the form reference.
So with f.show commented out, I still get:
Object reference not set to an instance of an object.
on this line of code:
f.Invoke(
New UpdateTextBox(AddressOf f.UpdateMessage), _ New Object() {strMonitorText})I don't know what to do and am getting desperate to resolve this. I really appreciate your help.
Thanks.
niceguy007
The same logic applies, just how you reference the control changes. Name all of your textboxes the same way, adding a numeric identifier:
TextBox1
TextBox2
...
TextBox100
Then, rather than 'Monitor.Text1(b+1) = Monitor.Text1(b) it would be:
Me.Controls("TextBox" & CStr(b + 1)).Text = Me.Controls("TextBox" & b.ToString).Text
(no default property in .Net).
If your WhiteMsgSub is in a module, then you will probably need to pass in the form object or add a public method on the target form that you can call.
XyMeXian Archer
I added the following code as suggested Spotty;
if f is nothing then
msgbox("not set")
else
f.show
end if
Now I get the error:
Cross-thread operation not valid: Control 'frmMonitor' accessed from a thread other than the thread it was created on.
Sorry but I'm really struggling to get my head around Threading and Delegates. :-(
Ashok Hurkat
Thanks for your response. I was just looking at the UpdateMessage code when you replied!
Here's the code:
Public
Sub UpdateMessage(ByVal strMonitorText As String) Dim intCounter1, intCounter2 As Integer For intCounter1 = 0 To 9 For intCounter2 = 8 To intCounter1 Step -1 Me.Controls("TextBox" & CStr(intCounter2 + 1)).Text = _ Me.Controls("TextBox" & intCounter2.ToString).Text NextarrTextBoxes(intCounter1) = strMonitorText
Next End SubEvery time the first for..next loop runs it jumps back to the f.invoke line and throws the exception. Is it because the argument that is passed is not referenced in that loop If so can you suggest another way that achieves the required result
Thanks
Ryan Darby
Exactly which line in the UpdateMessage routine fails Is it "For intCounter1 = 0 To 9" That would be a weird one... or does it make it to the first Me.Controls("TextBox" & Cstr... line
There are only a couple things in that routine that could cause the object reference exception...
1. The form must have 10 TextBox controls named "TextBox0" thru "TextBox9".
2. These 10 TextBoxes must be located on the form itself. That is, they cannot be in a GroupBox, Panel, or some other container (becuase the code is looking in Me.Controls, or the Form's control collection).
3. The arrTextBoxes object must be instanciated somewhere in this form, at the class level, before this routine is executed.
Can you give us the exact line that fails and verify these three items
StefaanV
Control arrays dont exists but you can reference control names by names.
The following creates an array (arr) and then writes the contents to a series of textboxes on a form called Textbox1, textbox2 and Textbox3 - I think this is sort of the basis of what you are trying to do.
In this case you would just create an array of however many textboxes you have on the form of the messages you want to display. How you create this array is down to you. Its a case of processing your source data and sorting and selecting the top items to you wish to display. You are only passing the items you want to display to this routine.
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'//Create an Array which I wantr to Display in textboxes
Dim arr(2) As String
arr(0) = "1 abc"
arr(1) = "2 def"
arr(2) = "3 ghi"
Foo(arr, "Textbox") '//Call the method
End Sub
''' <summary>
''' This will put the array into a series of textboxes all with the same Base Name
''' except for a number at the end. ie. Textbox1, Textbox2, textbox3
''' If control does not exist an exception will be thrown
''' </summary>
''' <param name="arr"></param>
''' <param name="textboxName"></param>
''' <remarks></remarks>
Sub Foo(ByVal arr() As String, ByVal textboxName As String)
Dim i As Integer = 1
For Each o As String In arr
Dim controlName As String = textboxName & i.ToString
Me.Controls(controlName).Text = arr(i - 1)
i += 1
Next
End Sub
End Class
Hope that points you in the right direction.
Nick Darnell
Sorry it's taken a few days to reply. It's a bit difficult to describe how this should work. Take a look at this piece of code from the VB6 version to see how it worked. This subprocedure was called for the lowest priority message, there are others that are called for higher priorities that order the text boxes slightly differently.
Public Sub WhiteMsgSub(strMonitorText)
For a = 0 To 11
If Monitor.Text1(a).BackColor <> vbRed And Monitor.Text1(a).BackColor <> vbYellow And Monitor.Text1(a).BackColor <> &H80FF& And Monitor.Text1(a).BackColor <> vbGreen Then
For b = 10 To a Step -1
Monitor.Text1(b + 1) = Monitor.Text1(b)
Monitor.Text1(b + 1).BackColor = Monitor.Text1(b).BackColor
Next b
Monitor.Text1(a) = strMonitorText
Monitor.Text1(a).BackColor = vbWhite
Exit For
End If
Next a
End Sub
ICIPeep
Thanks for your help again Spotty. F is instantiated with the following declaration:
Dim
f As frmMonitor = My.Application.OpenForms("frmMonitor")Is there anything wrong with this
Ron Walker
(I'm not sure what I did, but this screwy post is stuck at the bottom of the thread - please ignore it by now!)
Is the f.Invoke() code the line at which the exception occurs If not, please post the line of code that causes the exception. If it is this line, go into the UpdateMessage routine in 'f' and set a breakpoint so that you can step through it when called. The error may actually be occuring in here.
joey_sal
I have changed the code on the form but am getting this error message during runtime:
Object reference not set to an instance of an object.
The data that is entered into the text boxes is passed from a module with this code:
f.Invoke(New UpdateTextBox(AddressOf f.UpdateMessage), _
New Object() {strMonitorText})
Thanks for your help.
Admiralman
My.Application.Openforms will return a collection of forms already instantiated in the system. So I would initially say no. As you are setting a reference variable f not instantiating a new instance of frmMonitor.
Normally you would have to create an instance first.
Try the following experiment. Immediately after the line youve quoted this line put in these lines
if f is nothing then
msgbox("not set")
else
f.show
end if
My suspicion would be you'll get not set.
You need to instantiate an instance of frmMonitor somewhere for that line to stand a chance of working.
Now I'm not sure if you are trying to use the default instancing feature which would only allow a single instance of frmMonitor to exist. In which case the call would be the following. Now default instancing you dont need to put in new and it will work. Its a bit of a hack to cure a legacy VB6 issue.
Dim f As Form2 = My.Forms.Form2
Try the same block of code after this and it should work.