Visual Studio 2013 NullReferenceException SelectedItems.Clear - vb.net

I am in the process of converting my working VB 2010 forms application to Visual Studio 2013. I've encountered a nullreferenceexception where one does not occur in the old code. Basically, I start with a fresh instance of the form. The form contains a treeview and the user can navigate down through it and select a node. Based on their selection another portion of the form gets populated (a datagridview) with the associated elements. This is an explore screen.
When the user is done exploring, the application captures the node they were on and saves it. Immediately, the form is closed, disposed and set to nothing (NULL).
' Class variable definition
Private XInvenNode As New TreeNode
If fdiaXInven Is Nothing Then fdiaXInven = New diaExploreInven(True, True)
fdiaXInven.tvInven.SelectedNode = XInvenNode
fdiaXInven.ShowDialog()
XInvenNode = .tvInven.SelectedNode
results = .SelectedItems
fdiaXInven.Close()
fdiaXInven.Dispose()
fdiaXInven = Nothing
If the user returns to the explorer screen in the same session, it is instantiated again and the saved tree node is supposed to be restored so the user can continuing exploring in the same area. This is when the nullreferenceexception occurs.
I found this link and understand what a nullreferenceexception is. I've set breakpoints in the code and analyzed the contents of the variables within fdiaInven. It is not Nothing or NULL! For example, the following code worked perfectly on the first pass through but failed the second time:
fdiaInven.tvInven.SelectedNode = XInvenNode
What am I missing here? Are there some new rules in VB since the 2010 version that would cause this?

Related

ComboBox Unreadable in Multithreaded

I'm trying to build a small application that connects to a couple databases to move data from one to the other, manipulating and verifying data is it moves. I had everything working, but wanted to add the majority of the work to a second thread so that the initial window is still functional.
I have most of it working fine so far, except for one pesky bit. I allow the user to choose the database from a list of databases on a MSSQL Server. Without the threading, the program can read the text of the combo box without issue. As soon as I add in threading, it can't read the text of the combo box. It doesn't have issues reading the text boxes that contain the servername/username/password, just with this one combo box. The code below is in a class that handles all my database functions. The combobox is on the main form (frmMain) that is launched when you run the application. frmMain is the default form for the application.
Without threading I was doing this.
Me._sqlDB = New sqlDatabase
Me._sqlDB.DBServer = frmMain.txtServer.Text
Me._sqlDB.DBUsername = frmMain.txtUser.Text
Me._sqlDB.DBPassword = frmMain.txtPassword.Text
Me._sqlDB.DBDatabase = frmMain.cboSQLDatabase.Text
When I added the thread, it couldn't read from the combo box (along with a host of other issues due to non-threadsafe calls). I did some research and added in some delegates and invokes. This solved the rest of the issues I was running into, but the combobox was still unreadable.
I created a function with a delegate to read the combobox, hoping that it was a thread related issue, but still no luck. The database connection setup code is in the database class I mentioned above and the GetDatabaseName function is in the main form (frmMain).
'Database Connection Setup
Me._sqlDB = New sqlDatabase
Me._sqlDB.DBServer = frmMain.txtServer.Text
Me._sqlDB.DBUsername = frmMain.txtUser.Text
Me._sqlDB.DBPassword = frmMain.txtPassword.Text
Me._sqlDB.DBDatabase = frmMain.GetDatabaseName
'GetDatabaseName Function for Connection String Setup
Delegate Function GetDatabaseNameDel() As String
Public Function GetDatabaseName() As String
Dim DBName As String = ""
If Me.cboSQLDatabase.InvokeRequired Then
DBName = Me.Invoke(New GetDatabaseNameDel(AddressOf GetDatabaseName))
Else
DBName = Me.cboSQLDatabase.Text
End If
Return DBName
End Function
I have tried several of the combobox properties, including SelectedItem, SelectedText, and Text. None of them have any value when the GetDatabaseName function is called. In fact, when run in debug mode and pausing the code execution, Visual Studio shows that the combobox has nothing in it (Count = 0, Items collection is empty).
The combobox is populated using a SqlDataReader that reads the list of database names from the server.
I also tried changing the setup to use a BackgroundWorker, but I get the same results.
Any thoughts on why the combobox is appearing as empty when running as a separate thread?
With a little more research, I found a possible solution, but it seems really janky. If I change the call to the function to use this:
Me._sqlDB.DBDatabase = CType(My.Application.OpenForms.Item("frmMain"), frmMain).GetDatabaseName
It works, but this seems like a very odd workaround for the issue. Is there a better way to refer to the control on the active form?

The form referred to itself during construction from a default instance, which led to infinite recursion

I am currently trying to create a simple client (Initiator) using QuickFix with a graphical user interface. I'm using Visual Studio 2012 and programming in VB.Net.
Here is my problem :
When I launch my app, I have this error : "An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsApplication1.exe
Additional information: An error occurred creating the form. See Exception.InnerException for details. The error is: The form referred to itself during construction from a default instance, which led to infinite recursion. Within the Form's constructor refer to the form using 'Me.'"
I have two files in my project which are Client GUI.vb (http://pastebin.com/virgVNyS) and MyQuickFixApp.vb (http://pastebin.com/tQ1GXNSx). The second one contains the class that integrates the IApplication, with all the subs.
The error happens when it executes this line : "Dim initiator As New SocketInitiator(myApp, storeFactory, settings, logFactory)" from Client GUI.vb
but the software highlights a line from the file Application.Designer.vb which is :
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = Global.WindowsApplication1.ClientGUI
End Sub
Can you help me and tell me what is wrong ?
Thank you very much !
When dealing with WinForms, the best proceeding to avoid problems is initialise everything (except simple variable assignation, for example: Dim filename As String = "initiator.cfg" is fine) after the GUI has been constructed/loaded (on the _Load method). The reason why you are getting this error is because of referring to the main Form (Me.MainForm =) before it has been actually created.
Move Dim initiator As New SocketInitiator(myApp, storeFactory, settings, logFactory) to ClientGUI_Load (the Load Event method of your main form) and the error will disappear.
NOTE: if you want to access initiator from "anywhere", you should keep the global declaration but move the assignation to the Load event, that is:
Dim initiator As SocketInitiator 'at the Class level, outside any sub/function (as previously)
And
initiator = New SocketInitiator(myApp, storeFactory, settings, logFactory) 'Inside the ClientGUI_Load method.
I had a similar problem; I'm hoping my description of it and the solution I found may provide clarity to others in the future.
I declared two constants for a grid background color. Selected rows should be yellow. I also said that nonselected rows should be the default background color of one of the grids on the form:
Private MatchColor As Color = Color.Yellow
Private NormalColor As Color = MyFormsDataGridView.BackgroundColor ' <<< this line is bad.
This was in the form's declarations section, before any code could run! I got the error and was flummoxed for hours. I even read this post but it didn't sink in.
The problem of course is that I was referring to a property of a grid on a form that had not yet been instantiated!
The solution was:
Private MatchColor As Color = Color.Yellow
Private NormalColor As Color = Color.White ' <<< this is the fix.
Then it loaded just fine!
I hope that helps.

VS 2010 stops responding when opening form designer

I have VisualBasic project wih many forms,and one of it is form1.Whenever the initializecimponent method is called,VS stops responding and i have to end it using taskmgr.The bug is inside the form1.designer.vb, because i am able to view and edit other forms and usercontrols in designer.Anoter strange thing is that the stand alone exe runs successfully outside the IDE.I also tried adding the form to another project and that project too crashes.Whenever i build/debug/view form1 in designer, i get two dialogs one after the other:VS2010 has stopped working, VS2010 is restarting( but it never does!)
Create a copy of the form, and begin removing parts of the form until it works. The last thing you removed is what failed. You'll have to do this manually by removing three parts of each control:
The Declaration (at the bottom)
The instantiation (at the top)
The configuration (in the middle). Below is an example of the configuration
'
'LeftLabel
'
Me.LeftLabel.Anchor = System.Windows.Forms.AnchorStyles.Left
Me.LeftLabel.AutoSize = True
Me.LeftLabel.Location = New System.Drawing.Point(3, 3)
Me.LeftLabel.Name = "LeftLabel"
Me.LeftLabel.Size = New System.Drawing.Size(39, 13)
Me.LeftLabel.TabIndex = 1
Me.LeftLabel.Text = "Label2"
You'll also need to remove any references to that control, such as it being added to a container.
Do this one control at a time, then build the project and open the form. If the form does NOT open, restart visual studio and do the next control. if it DOES open, then the last thing you removed was the culprit.
For programmers facing the same problem, here is the solution:
Make sure that your user controls doesn't creates instances of themselves inside themselves.even though your program might run without any error, VS designer will crash.here is an example for such kind of code:
Public class controlx
public sub new()
dim x as new controlx
End sub
End class
you might think its a silly logical error, but such errors can be very much frustrating and time consuming.always breakdown your code to smaller units so that its manageable as Brian said.

Need to call com function from VB.NET

If anyone wants to take a crack at this I'd really appreciate it. I'm writing a VB.NET app that will control a commercial backup product. One of the things I need to do is loop through all existing jobs and look at the source drive. I am able to do this in VBScript very simply like this:
Dim SP, BackupJob, volumes
Set SP = CreateObject("ShadowStor.ShadowProtect")
For Each Job In SP.Jobs
Set BackupJob = SP.Jobs.GetBackupJob(Job.Description)
BackupJob.GetVolumes volumes
For Each Volume in volumes
WScript.Echo volume
Next
Next
Set SP = Nothing
However nothing I try in VB.NET works. I'm pretty sure it has to do with the fact that the com functions are returning variant data types and arrays (specifically GetVolumes). I have tried using string arrays, object arrays, and even wrapping the return value in a VariantWrapper and I always get errors such as "not implemented" or "the parameter is incorrect." If anyone is bored and wants to write some code I'll gladly give it a shot and report back.
UPDATE:
This is odd. Look at this code:
Dim SP As Object = CreateObject("ShadowStor.ShadowProtect")
Dim gotJob As Object
Dim volumes() As Object
Try
For Each Job As Object In SP.Jobs
gotJob = SP.Jobs.GetBackupJob(Job.Description.ToString())
gotJob.GetVolumes(volumes)
For Each volume As Object In volumes
MsgBox(volume.ToString())
Next
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
This will display the volume from ONE job, then it crashes if there is more than one jobwith the error "invalid callee."
Locate ShadowStor.ShadowProtect in your registry in HKCR. It will have a CLSID which is a GUID. Search for that GUID, also in HKCR. You should find it in the CLSID section. Under that key you should find the actual dll path under InprocServer32.
Now if that component has an embedded TypeLib you should be able to add a reference to it in Visual Studio. (If you have OLE View installed you can inspect the type lib easily as well).
And if you cannot add a reference to the dll, there might be a seperate .tlb file, and you can find that by searching on the GUID present in the TypeLib value.
For anyone interested, the solution was to Dim volumes() As Object inside the loop and then set volumes = Nothing at the end of the loop so that it was re-created each time. If anyone can explain why this is so I would love to understand it.

Openform action was canceled in MS-Access VBA code

I am supporting an application which was running for the past 3 years. It was developed completely in MS Access and written in VBA.
Suddenly the application is facing the mentioned error at the following lines:
DoCmd.OpenForm FormName:="frmNewPeerGroup", View:=acNormal, windowmode:=acWindowNormal, OpenArgs:=5
FrmNewPeerGroup code
Private Sub Form_Open(Cancel As Integer)
Dim lDept As Long, lDiv As Long
lType = OpenArgs 'Supplied by caller
lAssmtVer = 1 'Current
sName = ""
sDescription = ""
dtCreatedDate = Format(Now(), "dd/mm/yyyy")
sCreatedBy = UCase(userPerms.NTLoginName)
lSupervisorID = userPerms.userID
lTeam = 0
With cmbBxType
.RowSourceType = "Value List"
.RowSource = GetValueListDict(pgType)
.Value = lType
.Enabled = (OpenArgs = 1)
End With
With cmbBxVersion
.RowSourceType = "Value List"
.RowSource = GetValueListDict(pgAssmtType)
.Value = lAssmtVer
End With
mgLogoDesc.Visible = False
txtBxCreatedDate.Value = dtCreatedDate
txtBxCreatedBy.Value = sCreatedBy
If OpenArgs = 5 Then
lTeam = oActiveAssmt.TeamID
lDept = GetParentID(aTeams(), CInt(lTeam))
lDiv = GetParentID(aDepts(), CInt(lDept))
With cmbBxDivision
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aDivs())
.Value = lDiv
.Enabled = False
End With
With cmbBxDepartment
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aDepts())
.Value = lDept
.Enabled = False
End With
With cmbBxTeam
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aTeams())
.Value = lTeam
.Enabled = False
End With
Else
With cmbBxDivision
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aDivs())
.Enabled = False
End With
cmbBxDepartment.Enabled = False
cmbBxTeam.Enabled = False
End If
End Sub
Many instances of the DoCmd.OpenForm command are giving the error in a message box saying:
The expression On Click you entered as the event property setting
produced the following error: The OpenForm action was canceled.
- The expression may not result in the name of macro, the name of
a user-defined function, or [Event procedure].
- There may have been an error evaluating the function, event, or macro.
This is the error message I am receiving.
My problem is, the same code was running around 3 years, but suddenly some updates to Microsoft or Office might be giving trouble to this code.
Did anyone come across this error in the past weeks? Please let me know what else we can do to make this work again.
This thread is very old but I came across the same error and spent a few hours looking for an answer. I was able to find the cause after some time and thought of posting my answer as it may help someone in a similar situation. Creating a application using Access Forms is new to me, so the error message was not directly intuitive.
My forms were Master table data entry forms and configured to be Pop-up and Modal with Me.Form.Name sent as parameter in the DoCmd.OpenForm command using a button (OnClick event) placed next to the Combo controls on a transaction form to allow user to quickly add new records. This parameter value was picked up in the Form_Open(Cancel As Integer) event and used later to refresh the combo box (Forms!<formname>.Controls!<controlname>.Requery) once data was submitted to the master table using the pop-up form.
It appears that the Open event doesn't occur when you activate a form that's already open (ref: https://msdn.microsoft.com/en-us/library/office/aa211439(v=office.11).aspx). Each time I received the error, my data entry form was open in Design view in Access. So I closed the form in design mode, and repeated the steps. And Voila! no error!
Since I will have more than one forms open, I now need to test and try to use Form_Activate() as recommended in the above MSDN reference link.
I don't know if this qualifies as an answer, but the code in that OnOpen event is dependent on a lot of outside functions. Specifically, the code is assigning value lists for the RowSources of a bunch of combo boxes. The immediate red flag that occurs to me is that non-SQL Rowsources have a finite length, and in Access 97, that limit was 2048 characters (in Access 2003, it's 32,750 -- don't ask me why it's that number!).
So, the immediate thing I see is that perhaps what ever data drives the functions that create those value lists has begun to exceed 2048 characters in length.
If that's the actual answer, then you can write a callback function that will return the values in the arrays, and it won't have the limitation on the returned length. You'd set the RowsourceType to the name of your callback function and leave the Rowsource property blank.
An example of the callback function is found in the A97 help (though I can't find the same example in the A2K3 help). In A97 help, you get there by searching for RowsourceType, and then in the help window, click on the link in the sentence reading "You can also set the RowSourceType property with a ____user-defined function____."
To check this out, you just need to find out the length of the string returned from GetValueListArray() by each of the arrays referenced in the OnOpen event.
It also might be helpful to add an error handler to the OnOpen event, particularly given that there are so many outside dependencies in the code in that particular sub.
And last of all, let me say that it looks like horrible programming. Most of this ought to be settable with default properties, seems to me. I also question that kind of dependency on OpenArgs with such an undocumented input value. What does "5" mean? And what does "1" mean? Is that documented somewhere? It's just terrible, terrible code, in my opinion.
I'd likely do this with a standalone class module instead, because that will be self-documenting in terms of what does what. You'd set a particular named property to 5 and that would control what the form gets from the class module methods for populating the combo boxes. It would all be in one place, and you could use a meaningful property name to make it clear what the values 5 and 1 represent. It's particularly helpful to do this if you have the same kind of code in the OnOpen event of multiple forms. In that case, it's a no-brainer to move it out of the form modules, and the only question is whether you put it in a regular module or in a standalone class module (as I'm suggesting).
Anyway, perhaps none of this is on point, but it might give you some ideas.
Could it be the security settings is Access? All recent versions of Access has a security settings dialog where you can enable (or disable) macros in the application. I think you will get this error if macros are disabled.
Are you sure one of the required references (VBA IDE > Option > References) isn't missing?
If you're referencing Excel/Word or external objects, are you sure that the references to the type libraries are the right ones (if you're using specific versions instead of doing late binding)
Are you building the MDE on a 64 bit machine by any chance?
What is the code on the form frmNewPeerGroup? What version of Access are you using? If it is 2003, sp3 causes problems for which there is a hotfix. Have you tried decompile and / or compact and repair?
If you have an original mdb, check the references to make sure that none of them are marked MISSING. This is quite a likely reason for problem in that it has suddenly occurred.
To check the references, look at Tools->References on the menu for a code window.
If no references are missing, you could try stepping through the form code to get a more exact idea of where the error is occurring.