How to get checked state of Checked Listbox vb.net - vb.net

I have a checked listbox which I am running through and saving names to a database. As I run through I need to see if the check box is checked or clear.
I've tried the following code but to no avail:
If chklbRegister.GetItemCheckState(nLoop).ToString = "1" Then
.Parameters.AddWithValue("#sqlAttended", 1)
Else
.Parameters.AddWithValue("#sqlAttended", 0)
End If
I have also tried:
If chklbRegister.GetItemCheckState(nLoop) = True Then
but it still doesn't worked. Ideas please.
Thanks
Graham

GetItemCheckState returns an Enum. An enum is not a string and not a boolean.
You should test again the defined values of the enum
If chklbRegister.GetItemCheckState(nLoop) = CheckState.Checked Then
-----
If you apply the ToString method to an enum value you get the translated text of the enum, in your case the word "Checked" and not the string "1".
Of course, being the enums fundamentally numeric values of integral type you could always cast the return value to an integer, but you never should do it and use instead the proper Enum syntax
As a final note. This problem should have been signaled by the compiler and not slipped past the compilation phase. This compiler behavior is caused by the Option Strict set to Off instead of On. I suggest to change this option in the configuration of your project to avoid other errors of this kind that could be very subtle.

You can see for the documentation for GetItemCheckState that it returns a value from the CheckState enumeration so you need to check this:
chklbRegister.GetItemCheckState(nLoop) = CheckState.Checked

Related

How serious is BC42020 in an upgraded VB .Net project?

Consider the following line of code which used to compile without warnings.
Public SetUpDone = False
After upgrading a project to Visual Studio 2017 from Visual Studio 2005 over a hundred of these BC42020 warnings exist. The MSDN description of the warning simply states that the variable defaults to type object. I don't have a good idea of the seriousness of this type of warning. The debugger indicates that the code executes as I expect. Is it merely a performance type of issue?
Secondly, I thought that Visual Basic supported some form of Type Inference so I'm not clear about why it wouldn't be able to deduce that the type should be Bool.
Another example is the following where the function returns a String
Dim dayTxt = " " & GetTextFromIni("General", "Var50")
I would have thought that type inference would work here and deduce that dayTxt is a String.
This:
Public SetUpDone = False
Is equivalent to this:
Public SetUpDone As Object = False
As suggested, type inference is only for local variables, not fields. With Option Infer On, this inside a method:
Dim SetUpDone = False
would indeed be equivalent to this:
Dim SetUpDone As Boolean = False
There are a couple of issues with the code as you have it. Firstly, it means that every use of that False value requires unboxing which makes your code slower. That's the case for any value types, i.e. structures. Value types are normally stored on the stack but, when boxed, are stored on the heap.
Secondly, it means that any member access will require late binding. That's not an issue for Boolean values because they have no members of interest anyway but if it was, say, a DateTime then the IDE would never provide Intellisense for that type because al it would see would be type Object and the existence of the specified member would have to be confirmed at run time, making the code less efficient again.
Thirdly, it means that the compiler can never confirm that you're passing the correct type as a method argument. For instance, if you have a method with a Boolean parameter, the compiler won't know that you're passing a Boolean if you pass that field because it's type Object. That also means that if you pass some other Object variable that doesn't contain a Boolean, the compiler can't warn you.
As suggested, you should turn Option Strict On in the project properties. That will flag every instance of you're not specifying the appropriate type for something. Fixing those errors will, at the very least, make your code a bit more efficient. It may even draw your attention to situations where exceptions will or could be thrown at run time. Having Option Strict On enforces strict typing so it makes you think more about the types you're using. Even if you're conscientious about that with Option Strict Off, you can still make mistakes that Option Strict On will prevent.

Why does this simple string formating now throw exception?

I'm using Authorize.net API and they require card expiration field to be formated as "yyyy-mm". We did that with this simple line of code:
expirationDate = model.Year.ToString("D4") & "-" & model.Month.ToString("D2")
and this absolutelly worked. I still have cards stored in the system that were saved using this method! But today I was testing something completelly unrelated, and wanted to add another card, and bam, this code exploded with this exception:
System.InvalidCastException: 'Conversion from string "D4" to type 'Integer' is not valid.'
Inner exception to that one is:
Input string was not in a correct format.
This just... doesn't make sense to me. Why in the world is it trying to convert format specifier (D4) into an integer? What input string? What in the world changed in two days?
The problem is that your are using a Nullable(Of Integer). This is a different structure that does not support the overloads of the ToString method a normal Integer has.
You can view the overloads of the Nullable structure here.
I suggest you use the GetValueOrDefault() method to get the proper Integer and also apply the value you expect in case the value is Nothing.
If it is impossible that a instance with a Nothing set for the year reaches this method you can simply use the Value property.
I still do not fully understand why you get this strange error message. Maybe you could check out what the actual method that is called is? Pointing at the method should give you that information. It can't be Nullable(Of Integer).ToString
Well, I found a workable solution and something of an answer thanks to #Nitram's comment. The type of Year/Month property has been changed from Integer to Integer?. Obviously, this isn't a very satisfying answer because I still don't understand why the nullable int can't be formatted, and yet the code compiles perfectly. The working solution for me has been using static format method on String as so:
expirationDate = String.Format("{0:D4}-{1:D2}", model.Year, model.Month)
This works fine even with nullable types.

VB.NET LINQ Method Syntax disallows implicit conversions from 'Integer?' to 'Integer'

Compare weirdness when working with LINQ and Entity Framework.
I want to retrieve an ID from my DB and I get this weird message.
I could simply fix it as you can see but I want to understand why this happens.
Question:
Why do I get this error message even if I check with "HasValue" or I use "FirstOrDefault"? It can't be null in my opinion but I obviously miss something.
Add .Value if you are 100% sure the Integer? has a value.
Why do I get this error message even if I check with "HasValue"
Entity Framework just uses the objects you give it. It can't create a new object where OPX_ isn't nullable.
the setOpxRights function presumably takes an Integer as a parameter and Option Strict On won't allow an Integer? to be implicitly converted to an Integer. If you are sure that it will always have a value, pass in cctUser.OPX_Rechte.Value
The compiler is not perfect, we can see that OPX_Rechte will have a value because of the where statment, but for the compiler you are just using a the object cctUser that have an Integer? and it needs an Integer.

Setting a variable to null value in inline if statement

I'm trying to use the following code to check for a DBNull and set the variable to nothing if it is, or a short if it isn't. The problem is it is failing to set the variable to Nothing and sets it to a 0 instead. Anybody know why?
variable = If(currentRow.Item("variable") Is DBNull.Value,
Nothing, CShort(currentRow.Item("variable")))
If variable is declared As Short? then the code works with a slight tweak: you need to cast either operand of If to the target type first:
variable = If(condition, CType(Nothing, Short?), CShort(…))
(You could also have cast the third operand instead, or both.)
This cast is necessary because of how If deduces types: if the two result types mismatch, a common type is deduced which is the closest parent type, i.e. a type from which both inherit. However, with Nothing, new rules come into play because as far as VB is concerned, Nothing is already a valid Short – a default-initialised one (see old answer below for explanation). So VB doesn’t try any type coercion, it simply uses Short as the return value.
Old answer below, assuming that OP had declared variable As Short:
You cannot set value types to Nothing. If you assign Nothing to a value type then it will be set to its type’s default value instead – which is 0 for Short.
You can test this easily:
Dim s as Short = Nothing
Console.WriteLine(s)
Setting a value type to Nothing is the same as invoking its default constructor (New Short()) or declaring a new variable of that type without initialising it. The corresponding operation in C# would be to assign default(T) (short s = default(short)).
If you want to represent null value types, you have to use nullable types:
Dim s as Short? = Nothing
Now s is of type Nullable<Short> (Short? is a shortcut of that) and can be assigned a proper Nothing.

VB.NET Get underlying system.type from nullable type

I'm attempting to create a dataset based on the properties of an object. For example, I have an instance of a Person class with properties including ID, Forename, Surname, DOB etc. Using reflection, I'm adding columns to a new dataset based on the object properties:
For Each pi As PropertyInfo In person.GetType().GetProperties()
Dim column As New DataColumn(pi.Name, pi.PropertyType)
table.Columns.Add(column)
Next
My problem is that some of those properies are nullable types which aren't supported by datasets. Is there any way to extract the underlying system type from a nullable type?
Thanks.
Here's your answer, in VB. This may be overkill for your purposes, but it also might be useful to some other folks.
First off, here's the code to find out if you're dealing with a Nullable type:
Private Function IsNullableType(ByVal myType As Type) As Boolean
Return (myType.IsGenericType) AndAlso (myType.GetGenericTypeDefinition() Is GetType(Nullable(Of )))
End Function
Note the unusual syntax in the GetType. It's necessary. Just doing GetType(Nullable) as one of the commentors suggested did not work for me.
So, armed with that, you can do something like this... Here, in an ORM tool, I am trying to get values into a generic type that may or not be Nullable:
If (Not value Is Nothing) AndAlso IsNullableType(GetType(T)) Then
Dim UnderlyingType As Type = Nullable.GetUnderlyingType(GetType(T))
Me.InnerValue = Convert.ChangeType(value, UnderlyingType)
Else
Me.InnerValue = value
End If
Note that I check for Nothing in the first line because Convert.ChangeType will choke on it... You may not have that problem, but my situation is extremely open-ended.
Hopefully if I didn't answer your question directly, you can cannibalize this and get you where you need to go - but I just implemented this moments ago, and my tests are all passing.
Nullable.GetUnderylingType(myType)
will return the underlying type or null if it's not a nullable type.
I'm guessing that the problem is recognizing whether the property is nullable or not. In C# you do this with this code:
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
... but I'm not sure what the equivalent of that last clause is in VB.NET.
You can also use the GetGenericParameters() method on that type. myNullableObject.GetType().GetGenericParameters()[0] should give you the type of nullable it is (so Guid, Int32, etc.)
#Mendelt Siebenga: You can only call GetType on the value property if the variable is not set to null; otherwise, you'll get an exception.
What you want to do is use the "GetValueOrDefault" property and call GetType on that, since you are guaranteed it will not be null. Example:
Dim i As Nullable(Of Integer) = Nothing
Dim t As Type = i.GetValueOrDefault().GetType()