Sunday, April 13, 2008

Learn and Practice LINQ With LINQPad

LINQPad is a free tool that lets you query your databases using LINQ syntax in an IDE similar to a poor man's SQL Management Studio. It comes packed with 200+ examples.

image

You can also use it as a code snippet compiler, but I think Snippet Compiler is better suited for that, as LINQPad doesn't have Intellisense at the moment.

http://www.linqpad.net/

Friday, April 11, 2008

Development-Related Uses For Screencasts

I’ve started using a program called Jing recently. It can record a video of what's currently on your screen.

Possible uses:

  1. Show managers or project sponsors the current state of your in-progress application without giving them access to the version on your machine (that you might accidentally break since you're still working on it).
  2. When a new feature is created, developers could create a video that shows the QA team what the new feature is supposed to do.
  3. When the new feature doesn't work, the QA team can show the developers the steps necessary to reproduce the problem. (Most of the time, a simple text description isn't enough.)
  4. I have a friend who wants to show his users in Asia how to use certain features of his application.
  5. I have another friend who wants to record the repetitive (yet somewhat complicated) tasks he’s currently doing, so he can show someone else how to do those tasks.
  6. Project sponsors could keep customers (internal and external) abreast of new changes to an application via a blog and show off those changes with an embedded screencast.

If you want to get really fancy, you could even create tutorial videos like the kind you see on www.asp.net, but I think a program like Camtasia Studio would probably be better suited to that, as Jing has a 5 minute limit on any videos created, and there is no way to edit the videos it creates.

Also, because I don't want to divulge any company secrets, I'm not sharing my videos to Screencast.com, Jing's default video destination. I set it up to save a file on my hard drive, so that I can attach it to an email or TFS work item.

Jing is free and extremely easy to use.

http://www.jingproject.com/

How To: Hide a Button When Clicked on an ASP.NET Page Containing Validation Controls

Suppose you have a form with some ASP.NET validation controls on it, and you want to prevent users from clicking the form's submit button more than once.

image

It might sound easy at first. Just add some javascript to the asp:Button's OnClientClick to hide the button and show your custom message:

<script language="javascript" type="text/javascript">
function DisableButton(button)
{
button.style.display
= 'none';
document.getElementById(
'loading').style.display = 'inline';
}
</script>
<asp:Button ID="LoginButton" runat="server" Text="Login" OnClientClick="DisableButton(this)" />
<span id="loading" style="display: none;">Logging in...</span>

Except if you do that, and you're using ASP.NET validation controls on the page, your user could end up in a situation like this:

image

Now your user is stuck because the Login button is gone!

So, this is how to get around that:

<script language="javascript" type="text/javascript">
function DisableButton(button)
{
Page_ClientValidate();
if (Page_IsValid)
{
button.style.display
= 'none';
document.getElementById(
'loading').style.display = 'inline';
}
}
</script>

In the script above, you'll notice I'm using a Page_ClientValidate() method and a Page_IsValid boolean variable. Those are exposed as part of ASP.NET's Client-Side Validation API.

What's happening:

  1. Page_ClientValidate() forces the validation to happen immediately.
  2. If the validation tests pass (Page_IsValid), hide the button, show the message, and submit the page.
    image
  3. If the validation tests fail, ASP.NET will handle showing the validation errors for you, and the page will not be submitted.
    image

For more information on ASP.NET Validation, see this article on MSDN:
http://msdn2.microsoft.com/en-us/library/aa479045.aspx

Friday, April 4, 2008

Enhancing C#'s switch statement with a fluent API

A colleague pointed me to this article today.  It shows a very clever set of utility classes that can dramatically improve the usefulness of the "switch..case" concept.  Since the C# language can't be extended, it is implemented as a fluent API that tries to mimic the built-in switch statement.

The most interesting use to me is the generics-based double dispatch using delegates that enables a sort of visitor pattern:

void Do(Control c) 
{
new Switch(c)
.Case<Label>(l =>
{
// ...
})
.Case<Button>(b =>
{
// ...
})
.Default(cc =>
{
// ...
});
}



An interesting oddity of the implementation is that the various Case() overloads are implemented as Extension methods on the Switch types. That is the only thing I don't like in the linked article. It exploits a "feature" of Extension methods that sorta allows you to call methods on null references. The case "statements" (method calls) are short-circuited by returning null and additional calls to Case() check for the null "this" pointer (the fake "this" which is the first parameter to extension methods) and exits quickly. To me, this seems like abuse of extension methods since the same thing can easily be accomplished with a traditional class.



Here is a modified version of the Switch<T> class implemented as a simple class without the extension methods:




public class Switch<T>
{
public T Object { get; private set; }
private bool hasBroken = false;

public Switch(T obj)
{
this.Object = obj;
}

public Switch<T> Case(T other, Action<T> action)
{
return this.Case(other, action, SwitchBehavior.Break);
}

public Switch<T> Case(T other, Action<T> action, SwitchBehavior behavior)
{
return this.Case(x => object.Equals(x, other), action, behavior);
}

public Switch<T> Case(Func<T, bool> condition, Action<T> action)
{
return this.Case(condition, action, SwitchBehavior.Break);
}

public Switch<T> Case(Func<T, bool> condition, Action<T> action, SwitchBehavior behavior)
{
if (!this.hasBroken && condition(this.Object))
{
action(this.Object);
if (behavior == SwitchBehavior.Break)
this.hasBroken = true;
}

return this;
}

public void Default(Action<T> action)
{
this.Case(t => true, action, SwitchBehavior.Break);
}
}

public enum SwitchBehavior { FallThrough, Break }



A functional C# (type)switch - B# .NET Blog

Javascript: More than meets the eye...

I recently ran across a presentation on InfoQ by Glenn Vanderburg called "The Power of Javascript" that was recorded at JAOO.

Summary
Glenn Vanderburg makes the case for Javascript, a language long overlooked. This presentation from JAOO 2007 shows how its OOP model and other language features make it a very powerful tool and how to use these features to get the most out of the language.

The presentation describes how Javascript got its name - starting out as LiveScript developed by Netscape and later rebranded as Javascript to exploit the popularity of the new kid on the block - Java, developed by Sun. He explains why it is commonly considered to be a "toy language" and why it isn't.

A while ago I posted the first in a series of articles about javascript. Since then I've been somewhat stingy in releasing the other proposed articles.  I'll try to get back into the swing of things promptly.

Thursday, November 15, 2007

Sorting a Generic List of Custom Objects Simply

For a defect I was working on today, I just wanted to sort a list of users by username in a very simple fashion.

Google failed me. I wasn't able to find a good example of how to do this easily in VB.NET. As usual, most examples are full of noise, like this, this, this, or that.

So, once I figured out how to do it, I thought I should share it.

First, we create a function to handle our comparison.

Private Function UsernameComparer(ByVal x As User, ByVal y As User) As Integer
Return x.UserName.CompareTo(y.UserName)
End Function

Next, we use it.

myUserList.Sort(AddressOf UsernameComparer)

Now our user list is sorted by username.

In C# 2.0, using anonymous methods, it can even be done all at once:

myUserList.Sort(delegate(User x, User y) {
return x.UserName.CompareTo(y.UserName);
});

If you know of an even simpler way to do this, leave some comments and let us know!

Wednesday, October 17, 2007

MSDN code examples are terrible

This is the page that really got my goat. I'll list the relevant parts here for ease of reading.

Page.RegisterOnSubmitStatement Method

Allows a page to access the client OnSubmit event. The script should be a function call to client code registered elsewhere.

   1: '[Visual Basic] 
   2: Dim scriptString As String = "<script language=JavaScript> function doClick() {"
   3: scriptString += "document.write('<h4>' + myForm.myHiddenField.value+ '</h4>');}<"
   4: scriptString += "/" + "script>"
   5: RegisterHiddenField("myHiddenField", "Welcome to Microsoft .NET!") 
   6:  
   7: RegisterOnSubmitStatement("submit", "document.write('<h4>Submit button clicked.</h4>')") 
   8:  
   9: RegisterStartupScript("startup", scriptString) 


   1: //[C#] 
   2: void Page_Load(Object sender, EventArgs e) 
   3: { 
   4:    String scriptString = "<script language=JavaScript> function doClick() {";
   5:    scriptString += "document.write('<h4>' + myForm.myHiddenField.value+ '</h4>');}<";
   6:    scriptString += "/" + "script>";
   7:    RegisterHiddenField("myHiddenField", "Welcome to Microsoft .NET!"); 
   8:    RegisterOnSubmitStatement("submit", "document.write('<h4>Submit button clicked.</h4>')"); 
   9:    RegisterStartupScript("startup", scriptString);
  10: } 

Ok, how many things can you find wrong with this simple example?


  1. string concatenating to make a script block

  2. a bunch of totally unrelated code that muddies the point

  3. document.write() - who does that?

  4. VB and C# code don't even match; C# includes the method declaration; VB only includes the method body

  5. scriptString += "/" + "script>"

  6. definition says "The script should be a function call to client code registered elsewhere." but that is not what the example code does

Here's my stab:



   1: //[C#] 
   2: void Page_Load(Object sender, EventArgs e) 
   3: { 
   4:   if (!IsClientScriptBlockRegistered("doClickScriptKey"))
   5:   {
   6:     String scriptString = @"
   7:     <script type='text/javascript'>
   8:         function doClick() { alert('the form is about to submit!'); }
   9:     </script>";
  10:     RegisterClientScriptBlock("doClickScriptKey", scriptString);  //"registered elsewhere"
  11:   }
  12:   RegisterOnSubmitStatement("submitScriptKey", "doClick();"); //"function call to client code registered elsewhere"
  13: }