Wednesday, June 28, 2006

Most people that use C# are quite familiar with the if() expression and the (?:) conditional/ternary operator. In C# 2.0, the Visual C# team introduced another operator that's less known: the ?? or null coalescing operator. A quick demo explains how to use it. The result can be seen in Figure 1:

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 

    5 namespace ConsoleApplicationNullableTypes

    6 {

    7     class Program

    8     {

    9         static void Main(string[] args)

   10         {

   11             int? input = null;

   12 

   13             IfStatements(input);

   14 

   15             // Now fill up the nullable input with some value.

   16             input = 99999;

   17 

   18             IfStatements(input);

   19 

   20             Console.ReadLine();

   21         }

   22 

   23         /// <summary>

   24         /// Show the 3 different ways to write the same if functionality in C# 2.0.

   25         /// </summary>

   26         /// <param name="input"></param>

   27         private static void IfStatements(int? input)

   28         {

   29             int result;

   30             // Scenario 1, normal if statement

   31             if (input.HasValue)

   32                 result = input.Value;

   33             else

   34                 result = 200;

   35 

   36             Console.WriteLine("Scenario 1, result: " + result.ToString());

   37 

   38             // Scenario 2, using the conditional/ternary operator

   39             result = input.HasValue ? input.Value : 200;

   40 

   41             Console.WriteLine("Scenario 2, result: " + result.ToString());

   42 

   43             // Scenario 3, using the null coalescing operator new to C# 2.0.

   44             result = input ?? 200;

   45 

   46             Console.WriteLine("Scenario 3, result: " + result.ToString());

   47             Console.WriteLine();

   48         }

   49     }

   50 }

The 3 different manners of writing the same test. Scenario 1, line number 31, is the normal if statement. Scenario 2 uses the conditional/ternary operator and just like in scenario 1 the new method HasValue is used to check if the nullable type has a value. If so then one could fetch the value by using the Value property on the nullable type.
Scenario 3, line number 44, uses the new null coalescing operator which is only available in C# 2.0.

Since I started developing with C# 2.0 in May 2005 I used to use the code like described in scenario 2 until I found out about the null coalescing operator. I find it easier to read and to use in my code. But because I found out that not too many people seem to be aware of this new gem in the C# 2.0 language I wanted to show it off in an article.


Figure 1: The result of the test.

I also blogged about using testing serious with nullable types in the past: Be sure to put in some default value when testing with Nullable types in .NET 2.0.

Grz, Kris.  

kick it on DotNetKicks.com

Wednesday, June 28, 2006 7:59:22 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, June 25, 2006

Most controls are just drag & dropped on a webform or handcoded by a developer in the source view of the document. Although these controls can display dynamic data, for example coming from a database, the controls on the webform themselves remain static. In some scenario's however you want dynamically added controls. For example if a certain authenticated user views the page you want to show more information, or depending on a certain choice you want to load a Repeater control with data or a DateTime control. In this article I instantiate a RadioButtonList control, add it to a PlaceHolder control and wire up the SelectedIndexChanged event of the RadioButtonList instance. Listing 1 shows the C# version and Listing 2 the VB.NET version. Either version is equivalent and it's quite easy to compare both of the code snippets since both have the same equivalent code on the same line.

Listing 1: C# version:

    1 <%@ Page Language="C#" %>

    2 

    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    4 

    5 <script runat="server">

    6     protected override void OnInit(EventArgs e)

    7     {

    8         base.OnInit(e);

    9 

   10         // Instantiate a RadioButtonList control

   11         RadioButtonList rbl = new RadioButtonList();

   12 

   13         rbl.AutoPostBack = true;

   14         rbl.ID = "rblID";

   15 

   16         // Wire up the eventhandler

   17         rbl.SelectedIndexChanged += new EventHandler(rbl_SelectedIndexChanged);

   18 

   19         // Add the items

   20         rbl.Items.Add(new ListItem("One", "1"));

   21         rbl.Items.Add(new ListItem("Two", "2"));

   22         rbl.Items.Add(new ListItem("Three", "3"));

   23 

   24         rbl.DataBind();

   25 

   26         PlaceHolder1.Controls.Add(rbl);

   27     }

   28 

   29     void rbl_SelectedIndexChanged(object sender, EventArgs e)

   30     {

   31         // Get the control and cast it to the

   32         // appropriate type. In our case a RadioButtonList.

   33         RadioButtonList c = (RadioButtonList)FindControl("rblID");

   34         Label1.Text = c.SelectedItem.Text;

   35     }

   36 </script>

   37 

   38 <html xmlns="http://www.w3.org/1999/xhtml" >

   39 <head runat="server">

   40     <title>Untitled Page</title>

   41 </head>

   42 <body>

   43     <form id="form1" runat="server">

   44     <div>

   45         <asp:PlaceHolder ID="PlaceHolder1" runat="server" /><br />

   46         <asp:Label runat="server" ID="Label1" />

   47     </div>

   48     </form>

   49 </body>

   50 </html>

Listing 2: VB.NET version:

    1 <%@ Page Language="VB" %>

    2 

    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    4 

    5 <script runat="server">

    6 

    7     Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)

    8 

    9 

   10         ' Instantiate a RadioButtonList control

   11         Dim rbl As New RadioButtonList

   12 

   13         rbl.AutoPostBack = True

   14         rbl.ID = "rblID"

   15 

   16         ' Wire up the event handler

   17         AddHandler rbl.SelectedIndexChanged, AddressOf rbl_SelectedIndexChanged

   18 

   19         ' Add the items

   20         rbl.Items.Add(New ListItem("One", "1"))

   21         rbl.Items.Add(New ListItem("Two", "2"))

   22         rbl.Items.Add(New ListItem("Three", "3"))

   23 

   24         rbl.DataBind()

   25 

   26         PlaceHolder1.Controls.Add(rbl)

   27 

   28     End Sub

   29 

   30     Protected Sub rbl_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

   31 

   32         ' Get the control and cast it to the

   33         ' appropriate type. In our case a RadioButtonList.

   34         Dim c As RadioButtonList = DirectCast(FindControl("rblID"), RadioButtonList)

   35         Label1.Text = c.SelectedItem.Text

   36 

   37     End Sub

   38 

   39 </script>

   40 

   41 <html xmlns="http://www.w3.org/1999/xhtml">

   42 <head runat="server">

   43     <title>Untitled Page</title>

   44 </head>

   45 <body>

   46     <form id="form1" runat="server">

   47         <div>

   48             <asp:PlaceHolder ID="PlaceHolder1" runat="server" /><br />

   49             <asp:Label runat="server" ID="Label1" />

   50         </div>

   51     </form>

   52 </body>

   53 </html>

On line 11 the RadioButtonList is instantiated. After that it's given an ID and the AutoPostBack property is set to true (line numbers 13 & 14).
Then we wire up the event that'll be handled when a certain selection is made, remember we set the AutoPostBack property to true so once another choice than the current is made an automatic postback to the server will occur. Note the different syntax for C# and VB.NET to wire event handlers on line 17.

At this moment we already have a RadioButtonList instance, wired up the SelectedIndexChanged event, added 3 items to it and databound these items (Lines 20 to 24) but at this moment it's still not visible to the enduser since it was not already put on the page. ASP.NET provides a dedicated control for this: the PlaceHolder control. You can place this control somewhere on your webform and later on use it to hang dynamic controls to. Another convenient control for this is the Panel control. Adding our RadioButtonList to the PlaceHolder control is done on line 26.

We can now render our webform in a browser and upon checking a radiobutton in the list an automatic postback occurs, goes through the code of adding the RadioButtonList again to the page in the Page_Init/OnInit event again, which is necessary because the page has completely forgotten about the existance of it after the previous rendering. After that the rbl_SelectedIndexChanged event gets handled.
In this event we first need to obtain the correct control based upon its ID property with the FindControl method. This method returns an instance of a Control class, which is the base class of all controls in ASP.NET. Once obtained we need to cast it back to the proper class, which is in this case a RadioButtonList. Once cast the Text property of the SelectedItem is used to fill up the Text property of the Label control.

Grz, Kris.

Sunday, June 25, 2006 1:13:21 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, June 24, 2006

You know that your collegue has created a class with interesting method that you like to reuse in your ASP.NET 2.0 web project but your project is in C#. Instead of waisting time to rewriting the whole chunk of code that your collegue wrote you can simply reuse the code. The only need is to create a couple of subfolders, putting your classes, C# and VB.NET, in these separate subfolders and put some extra configuration in the web.config file.

So for example you add these subfolders to the App_Code folder: CSharp and VB.

In the web.config you put these lines in the <compilation> element:

  <system.web>

    <compilation debug="true">

      <codeSubDirectories>

        <add directoryName="CSharp"/>

        <add directoryName="VB"/>

      </codeSubDirectories>

    </compilation>



  </
system.web>

Another nice thing about this is that you could also use it to organise your classes somewhat better. For example you can create several subdirectories which hold business classes that belong together and make them known in the <codeSubDirectories> element.

Grz, Kris.

Saturday, June 24, 2006 5:49:25 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  |  Trackback

Last thursday I attended a session presented by Jan Tielens in Mechelen on the subject of Office 2007.
The session was dedicated for developers and because I haven't tried it out myself I found the new possibilities of Office 2007 very interesting. Especially the new file formats and the distinction between macro enabled and macro disabled documents are great. I still remember the time that macro virusses became available and the harm they could do to someones computer. Also the files themselves are smaller than in the past because they're, behind the scenes, compressed zip files. So in order to take a look at what's inside you just have to rename the file and add .zip behind the file extension of the document and you can open it with winzip for example. After that you can clearly see that all the data is now inside xml files and there are dedicated subfolders available to hold the embedded data like for example images.

The fact that the data is now xml means that a developer can quite easily manipulate the data, or create documents, with .NET. Especially because the next version will hold extra capabilities to interact with the so called "packages".

Besides the new file formats and what a developer can do with it we also had a demo about how to use the VSTO to create custom task panes or to create custom ribbons.

Well, I hope to get into experimentation on this topic soon because it really looks great to me.

Grz, Kris.

 | 
Saturday, June 24, 2006 5:30:22 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, June 21, 2006

Hi,

I found out, via Jan Tielens' blog, whom found out via Eli Robillard's blog, that you can download a 236 pages free eBook in pdf format about 7 Development Projects with the 2007 Microsoft Office System and Windows SharePoint Services 2007.

So for all you guys and girls interested: get your copy here.

Grz, Kris.

Wednesday, June 21, 2006 2:51:36 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, June 20, 2006

After months of using the Beta variant of this new incarnation of messenger, and with a rechristianed name that makes it a part of the whole new Live productline, I got my hands on the final bits. Since I installed IE7 Beta 2 I also put http://search.live.com/ as my personal home page. I really dig the AJAXised scrollable overview of the found resources. If you haven't checked it out yet, you really should!

If you want your copy just browse to http://get.live.com/messenger/overview.

Grz, Kris.

Tuesday, June 20, 2006 7:24:26 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, June 19, 2006

I like it when I'm in very large solutions with a lot of projects that my Solution Explorer of vs.net highlights the currently opened file instead of searching/scrolling around. In the previous versions this was enabled by default but for some reason Microsoft decided to don't have it as a default in vs.net 2005.

You can however enable this small but helpfull feature by navigating to the menu bar. Click Tools | Options and open the node called Projects and Solutions. You should see a modal window like Figure 1. Just check the checkbox labeled Track Active Item in Solution Explorer and you're good to go.


Figure 1: The options for Projects and Solutions.

Grz, Kris.

Monday, June 19, 2006 8:07:37 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, June 18, 2006

A lot of people, myself included, like to see the line numbers on each line while coding. I find it easer to remember where my code is but also to use the ctrl + g (goto line number) shortcut. By default this feature is disabled but luckely it's quite easy to turn it on.

Just navigate to the menu, choose Tools | Options and this expand the Text editor node in the treeview on the left like shown in Figure 1:


Figure 1: The expanded Text Editor part

There you can choose the All languages node or the node of the language that you're interested in and check the Line numbers checkbox. Click the OK button and you have the line numbers appearing in your source view.

Grz, Kris.

Sunday, June 18, 2006 5:23:51 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  |  Trackback

Nullable types in .NET 2.0 are a great asset for many developers. I use them all the time in my current project. However there are some things that you should be aware of. Because they can be filled in or can be null you should perform some extra checks in order to get your code to behave like you would expect it.

I've written some sample code that uses a nullable DateTime endDate. In applications this can be used to denote a period, startDate - endDate with the endDate being as such that it will never expire. In .NET 1.x we would've just filled it up with new DateTime(9999, 12, 31);. With nullable types you can just let it be null and check appropriately.

    1 <%@ Page Language="C#"%>

    2 

    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    4 

    5 <script runat="server">

    6 

    7     protected void Page_Load(object sender, EventArgs e)

    8     {

    9         DateTime startDate = newDateTime(2004, 5, 23);

   10 

   11         // Using a nullable DateTime can represent an occurance that doesn't expire.

   12         // In a database, like SQL Server, you can have this field set to NULL.

   13         DateTime? endDate = null;

   14         DateTime toCheck = newDateTime(2006, 6, 13);

   15 

   16         // First example: this test will fail because we check

   17         // a normal DateTime against a nullable DateTime without

   18         // replacing it with something to check against when it's null.

   19         // Note however that this code compiles! It's only not working out

   20         // in a functional logic way because it doesn't do what we would expect.

   21         if (startDate <= toCheck && toCheck < endDate)

   22             LabelEndDateNull.Text = true.ToString();

   23         else

   24             LabelEndDateNull.Text = false.ToString();

   25 

   26 

   27         // Second example: now we're checking, and replacing it with an appropriate

   28         // value in case it's null, so the test will pass as expected.

   29         // The trick here is to use the GetValueOrDefault() method on a Nullable type

   30         // to replace it with a default value in case it's null.

   31         if (startDate <= toCheck && toCheck < endDate.GetValueOrDefault(DateTime.MaxValue))

   32             LabelEndDateNullButWithGetValueOrDefaultUsage.Text = true.ToString();

   33         else

   34             LabelEndDateNullButWithGetValueOrDefaultUsage.Text = false.ToString();

   35 

   36         // Third example: this one's exactly the same as the previous, second, example.

   37         // Only here I'm applying the great ?? operator available in C# 2.0.

   38         if (startDate <= toCheck && toCheck < (endDate ?? DateTime.MaxValue))

   39             LabelEndDateNullButWithCheck.Text = true.ToString();

   40         else

   41             LabelEndDateNullButWithCheck.Text = false.ToString();

   42 

   43 

   44         // Fourth example: fill up the nullable DateTime with some actual value:

   45         endDate = newDateTime(2007, 1, 1);

   46 

   47         // We can see, this is easier when done debugging the code, that the enddate

   48         // now has some actual value and the test will pass.

   49         if (startDate <= toCheck && toCheck < (endDate ?? DateTime.MaxValue))

   50             LabelEndDateNotNull.Text = true.ToString();

   51         else

   52             LabelEndDateNotNull.Text = false.ToString();

   53     }

   54 

   55 </script>

   56 

   57 <html xmlns="http://www.w3.org/1999/xhtml">

   58 <head runat="server">

   59     <title>Untitled Page</title>

   60 </head>

   61 <body>

   62     <form id="form1" runat="server">

   63     <div>

   64         Enddate = null:

   65         <asp:Label ID="LabelEndDateNull" runat="server"></asp:Label>

   66         <br/>

   67         <br/>

   68         Enddate = null but with GetValueOrDefault method:

   69         <asp:Label ID="LabelEndDateNullButWithGetValueOrDefaultUsage" runat="server"></asp:Label>

   70         <br/>

   71         <br/>

   72         Enddate = null but with ?? check:

   73         <asp:Label ID="LabelEndDateNullButWithCheck" runat="server"></asp:Label><br/>

   74         <br/>

   75         EndDate != null:

   76         <asp:Label ID="LabelEndDateNotNull" runat="server"></asp:Label></div>

   77     </form>

   78 </body>

   79 </html>

The output of this little code sample is:

Enddate = null: False

Enddate = null but with GetValueOrDefault method: True

Enddate = null but with ?? check: True

EndDate != null: True

 

Take a look at the comment in the code, or better yet: debug it on your own dev machine, to see the subtle difference between the first and second example. The third example's just the same as the second but uses the ?? operator, the one that I prefer in my code because its shorter. The ?? operator, or null coalescing operator, is only available in C# 2.0.

Grz, Kris.

kick it on DotNetKicks.com

Sunday, June 18, 2006 12:01:24 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback

I'm probably very late with this but finally decided to join del.icio.us so finally people can also see what I like to read or am interested in.

For people who don't know this service:

del.icio.us is a collection of favorites - yours and everyone else's. Use del.icio.us to:

  • Keep links to your favorite articles, blogs, music, restaurant reviews, and more on del.icio.us and access them from any computer on the web.
  • Share favorites with friends, family, and colleagues.
  • Discover new things. Everything on del.icio.us is someone's favorite - they've already done the work of finding it. Explore and enjoy.

Grz, Kris.

Sunday, June 18, 2006 9:43:06 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, June 13, 2006

I just found out about the existence of this newly dedicated site: netfx3. After blogging already about the renamed WinFX to .NET 3.0 framework name it seems Microsoft's dedicated to the new naming.

Grz, Kris.

 |  |  |  |  | 
Tuesday, June 13, 2006 2:55:06 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  |  Trackback