Disabling all forms from a separate thread.


You may find yourself in a scenario where you need to disable all forms in your application but the event is triggered from a separate thread.  This is specifically useful if you are using a background thread to check if there are any updates available for your application. You may also just want to set any property on a form from a thread, and if you do you likely have run into this little exception:

Cross-thread operation not valid

Traditionally my solution would have been to crate a new method in the form that could be triggered using an invoke command, however lambda  has given me a new option, creating a new sub in code and applying it to the form during run time. Here’s what I created:

For Each frm As Form In Application.OpenForms
  Dim m As System.Delegate = Sub() frm.Enabled = False

Simple, yet powerful.




An interesting site I recently did some consulting for.  It’s not much right now, but they have a very sophisticated selling platform that is almost ready to bring to the public.

They think they are going to one up eBay, and maybe even amazon.

eVendors.net, a network of independent electronic vendors.

Calling VB6 from VB.NET


You may be aware of the “Interop Toolkit” for Visual Basic 6 and .NET that allows you to call .NET code from visual basic 6.  This is a nice feature but If you are trying to migrate out of VB6 the toolkit more or less forces you to keep your main application window to be a VB6 application.   Many people have asked Microsoft to make the tool kit work both ways but to date Microsoft has ignored these pleas. The vbGuru shares your pain, he has been working with a company that is migrating 20 years of VB6 code over to .NET while new requirements are constantly being added. All with a very small team.  (I think they’ve been working on it for over 10 years now, but are still stuck with lot of VB6 code.)

I have figured out a way for them to use an Interop approach that allows the main application to be VB.NET and uses an Interop style to call VB6 code (including forms) whenever legacy code has not yet been replaced.  And it is actually very easy for anyone to do in about 5 easy steps:


1) Convert your VB6 EXE project into an ActiveX EXE project.

2) Add a public class library and expose everything you need from your application.

3) Create a new project (can not be in the same project group) that is an Active X DLL.

4) In the Active X DLL Project, Reference the ActiveX EXE.

5) In your .NET project Reference the Active X DLL.

You can’t reference an Active X EXE in .NET, which would make this even simpler, but you can reference it from an ActiveX DLL.

Inside the ActiveX EXE I created a class Named “LegacyForms.cls”

Inside of it I created a public method for every form in my existing project:

Public Sub ShowfrmMain()


End Sub

Inside the ActiveX DLL I created a Public Class Called “Legacy.cls” which had a public method like so:

Public Sub ShowfrmMain()
  Dim fLeagcy As New Legacy.LegacyForms
End Sub

Now form my VB.NET code I can call:


It’s very easy to pass information to the VB6 code by just adding parameters to the public methods, sending data back to VB.NET is a little more tricky, but it can be achieved with public properties, methods, or if you want to be super fancy you could raise an event back to VB.NET.

Hope that makes sense.

Setting a Property Value on initialization with Linq


Before Linq if you wanted to set a property of any object you had to do it with two lines of code, like so:

Private Class NameValue
Public Name As String
Public Value As String
End Class

Private Sub SetNV()
Dim nv As NameValue = New NameValue()
nv.Name = "UserName"
nv.Value = "vbguru"
End Sub

Now with Linq you can do all of that in just one line of code and it works on any object whether it’s one you built or one built into the .NET framework using a “With” statement:

Private Class NameValue
Public Name As String
Public Value As String
End Class

Private Sub SetNV()
Dim nv As NameValue = New NameValue With {.Name = "UserName", .Value = "vbguru"}
End Sub

Using Linq to find the Max Value of a custom object property.


So I have a list of a custom object that has an integer property and I want the max value of that property from all of the items in the list. And I want it in one line of code.

 Dim MaxValue As Integer = myobjlist.Max(Function(x) x.Value)

That will check all the items in your list and return the highest value from the property named “Value”. Pretty dang sweet huh?

Linq Convert a Custom Object Property into a String


As I dive into Linq more I find the coolest solutions.

What I have trained myself to do is whenever I write a for loop, I ask myself can this be done in Linq? Usually the answer is yes. Today I was working on a function that created the Where clause for a Dynamic SQL statement.

At first I wrote a 10 line function that irritated through my “SearchTerms” object. And constructed a string, like so:

Private Function ReturnWhere(lWhere As List(Of SearchTerms)) As String
Dim sSQL As StringBuilder = New StringBuilder
Dim bFirst As Boolean = True
For Each ST As SearchTerms In lWhere
If bFirst = False Then sSQL.Append(" AND ")
bFirst = False
Return sSQL.ToString
End Function

After I was done I thought, can this be done in Linq? So with a little bit google’s help I came up with the following line of code:

Private Function ReturnWhere(lWhere As List(Of SearchTerms)) As String
Return String.Join(" AND ", lWhere.Select(Function(x) x.DBField & x.Comparer & x.Value))
End Function

Can you believe it? One line of code! I decided to dive deeper and see if I could get rid of the String.Join.

lWhere.[Select](Function(x) x.DBField & x.Comparer & x.Value).Aggregate(Function(x, y) x & " AND " & y)

However I found on the internet that String.Join has better performance then Aggregate so I decided against using it, and plus the String.Join line is easier to read.

SQL Server 2008 SSMS won’t remember password


SQL Server 2008 SSMS won’t remember password

Found this post, it worked for me, so I thought I’d share it.

There is a solution for this in SSMS 2012 that worked for me. Microsoft now provides a mechanism for removing a server from the list of remembered servers, and removing the offending server from the list will allow you to save the password the next time you connect to it:

  1. In the Connect to Database Engine dialog, drop down the server name list
  2. Use the arrow keys to select the server for which passwords aren’t remembered
  3. Press the delete key on the keyboard.