Dave's Notebook

Validating A WebForms Checkbox . . .

. . . and other ASP.NET controls that the Validation controls can not be wired to. The presentation today may be something you already know how to do. But, this question comes up repeatedly in my work as a .NET coach, which means there are still people who don’t know how to do this. There are other people who think they know how to do this but are hacking the solution. I encourage you to watch the video. My bet is that 80% of you that do will learn something you didn’t already know about the validation controls and how to use them properly. Here’s the basic problem. There are controls in the .NET framework that can not be wired to the standard validation controls. The checkbox control is one example. You can’t use the RequiredFieldValidator because it has a value. It’s either true or false. And you can’t provide a RegularExpressionValidator or one of the others because it is a boolean value. So, if I want to make sure a check box is checked before the user continues, for example. And, I want to make sure that the error message shows up in the error summary control like every other error, how do I do that?

The VB.NET Ternary Operator

I think the VB.NET Ternary Operator may be the last operator that I really miss in VB.NET from my curly brace language experience. Although, I have to admit, I wouldn’t have missed it all that much if they never added it. There just isn’t a whole lot of use for it. However, the Ternary operator is a REALLY nice feature to have available to you when you do need it. It’s another one of those language features that falls under, “Just because it is there doesn’t mean you have to use it.” If you’ve ever run into a situation where you just need a simple evaluation and assign a variable based on it. Like this:

Dim s As String 
If Session("mySessionVar") Is Nothing Then 
    s = String.Empty 
Else 
    s = Session("mySessionVar").ToString() 
End If 

you’ll appreciate the new Ternary operator which shrinks it to:

Dim s As String 
s = If(Session("mySessionVar") Is Nothing, _ 
       String.Empty, Session("mySessionVar").ToString)

Note that this NOT the same as

Dim s As String 
s = IIf(Session("mySessionVar") Is Nothing, _ 
       String.Empty, Session("mySessionVar").ToString)

Here’s the difference between the two. IIf will always evaluate the second and third parameter regardless of if the first parameter evaluates to true or false. This is because IIf is a function, not an operator. If is an operator, and therefore only evaluates the second OR third parameter when they are the value that will ultimately be returned. So, If() will run my code above without any errors while IIf will throw a null pointer exception when Session(“mySessionVar”) evaluates to nothing because it will try to apply ToString() to the object that is null

Object Initialization in CSharp 3.0 and VB.NET 9

Yesterday we looked at the new var keyword in CSharp. This makes CSharp variable declaration similar to VB. After all, they’ve had the DIM keyword for years which essentially does the same thing. Today, we’re going to look at object initializers, which have been added to both CSharp and VB. Let’s say we have a class named, “Customer” with the properties: FirstName, LastName, Address, City, and State. If you wanted to initialize those properties as part of the object creation process you basically had two choices. You could create a constructor with each of the properties represented as a parameter, or you could use the default constructor and then initialize each property individually immediately after you instantiate the object. Using CSharp, that process would look something like:

Customer c = new Customer() 
c.FirstName = "Dave"; 
c.LastName = "Bush";

in VB you could write code similar to the CSharp code above, with obvious syntax changes for VB, or you could use the WITH keyword to simplify it.

Dim c As New Customer() 
With c 
    .FirstName = "Dave" 
    .LastName = "Bush" 
End With 

The new versions of these languages make the initialization process a bit easier. Now, your CSharp code can look like:

Customer c = new Customer() 
{ 
    FirstName = "Dave", 
    LastName = "Bush" 
};

and your VB code can look like this:

Dim c As New Customer() With { _ 
.FirstName = "Dave", _ 
.LastName = "Bush" _ 
}

Keep in mind that the code that I just wrote compiles into the code I wrote using the old syntax. This means that we can use this syntax in Visual Studio 2008 even if we are writing code for .NET 2.0. Secondly, this means that it would still be faster to use the constructor with parameters if it is available. My fear is that some of the new features in the compilers will allow lazy programmers to write crappy code. The point of the object initialization syntax is not to help you avoid creating parameterized constructors. The point is to make your coding life easier when, and only when, the proper parameterized constructors do not exist.

CSharp adds the var keyword!

There have been several new features added to the CSharp language that will significantly reduce the amount of code that ends up in our source files. It will not significantly reduce the amount of code that we have to write. One of those language features is the ability to create properties, which we looked at last week. Another of those features is the new var keyword. So, instead of writing:

MyClass c = new MyClass();

you can now write:

var c = new MyClass();

Which isn’t a lot of code until you start qualifying the Class name with namespaces. During the beta cycle, I saw a demo that let you declare a variable, var c, and then several lines later initialize it with, new MyClass(), which gave the appearance that var was more like the var keyword in javascript, and therefore a variant than what it really is. In the release version of CSharp 3.0, if you use the var keyword to declare a variable, you MUST initialize it on the same line, or you will get a compiler error. I suppose it makes writing the compiler a whole lot easier this way too. One other small thing to note, which should be obvious by now. Since we have to initialize the variable to some object or value, and since we can’t initialize it anywhere other than on the line it is declared on, you can’t treat the variable as a variant. A variable declared as var is as strongly typed as any other variable you would create. So, if I did something like this:

var c = new MyClass(); 
c = "Some string here";

I would get a compiler error because I’m trying to assign a string type to a MyClass variable. var does not stand for “variant,” it stands for “variable.” All the compiler does when it sees this is look at the type being assigned to the variable and replaces the var keyword with that type. So, when the compiler processes the code, it takes this: var c = new MyClass(); and turns it into this: MyClass c = new MyClass(); Finally, it may be helpful to point out here that this whole process happens at compile time. This should be obvious by the fact that this works in both .NET 2.0 code compiled with the CSharp 3.0 compiler as well as .NET 3.x code. But, sometimes the obvious isn’t obvious until someone states it explicitly.

Simple Properties in C# 3.5

It’s such a little thing. But, how much of our CSharp code looks something like this:

private string _propertyName;     

public string PropertyName 
{ 
    get { return _propertyName; } 
    set { _propertyName = value; } 
}

When I teach other programmers how to use CSharp (or VB) I always stress the importance of using properties instead of public member variables. You never know when you’ll want your set to do some sort of validation and just about all of the databinding stuff requires us to use properties instead of member variables. But, that’s a lot of code to write when all you want to do is wrap a member variable. Well, in CSharp 3.5, life just got a lot sweeter. That code above just got replace with this: public string PropertyName { get; set; } You can still use the code above if you want to. But, why write all that code, even if you write it using a code snippet, when you can just write that one line?

Assign Multiple enum Values To One Variable

I saw this question and immediately thought, “You can’t! An Enum is an Integer that has been restricted to the values it can accept.”

And I was basically right. But, I forgot that even with an integer you can do the following in CSharp:

image

int i = 1 | 2;

And in VB.NET

Dim i As Integer = 1 Or 2

To end up with a variable i equal to 3 because both do bitwise ands.

So if I had an enumerated value

enum F {
thing1 = 1,
thing2 = 2,
thing3 = 4
}

Or, in VB.NET

Enum F
thing1 = 1
thing2 = 2
thing3 = 4
End Enum

You could then do the following in CSharp:

F fvar;

fvar = F.thing1 | F.thing2;

Or you could do it in VB.NET like this:

Dim fvar As F = F.thing1 Or F.thing2

There’s just one small problem with doing all of this.

If you evaluate fvar, you see that it is equal to 3 because we did not define 3 to be a specific value in our enumeration. However, by adding the Flags attribute to our enum definition:

[Flags]enum F {
thing1 = 1,
thing2 = 2,
thing3 = 4
}

Or

<Flags()> _Enum F
thing1 = 1
thing2 = 2
thing3 = 4
End Enum

fvar will evaluate to:

thing1 | thing2

in CSharp and in VB.NET…

Well, in VB.NET it still evaluates to 3.

ASP.NET GridView Edit All Rows At Once

I just saw a question about this yesterday and realized that while I know how to do this, not everyone does. So, here we go…

Here’s the problem. You want to be able to edit all of the rows in the gridview at once instead of having to switch to edit mode and save one row at the time. Normally, you’d want to do this when only a couple of items need to be changed per row and not the entire row’s worth of data.

image

Photo credit: tico_24 via VisualHunt.com / CC BY

You can do this easily if you make the columns that need to be edited templated columns and place editable controls in them (checkbox, textbox, etc) You can then either make these controls “AutoPostback” controls, or you can provide a control at the bottom of the screen that triggers the update. In either case, the code you are going to write at the codebehind level is going to be the same.

For this example, we are going to assume that you only have one column that needs to be updated and that the control is a checkbox control.

One of the issues you are going to run into with this is that you’ll need to know which row is associated with the control when it is updated. The easiest way I’ve found of dealing with this problem is by adding a HiddenField control and databinding the row Id to it. Since we are dealing with a CheckBox control, you will need to create an event handler for the Checked event. The first parameter that will be passed into this event handler will be the sender. Sender represents the control that fired the event. In this case, it will represent the CheckBox control.

The other control you’ll need to retrieve is the HiddenField control that you placed next to the check box. You can retrieve this control by using the FindControl() method that is hanging off the parent control of the check box. Assuming your HiddenField control is named “_hiddenFieldId” you can get the ID by using:

string id = (HiddenField)(((CheckBox)(Sender)).Parent
.FindControl(“_hiddenFieldId”)).Text;

Now that you have the value of the ID and the value of the checkbox, you can update your database.