Brendan Enrick

Daily Software Development

Creating a Recursive FindControl Extension Method

So one of the most useful methods for ASP.NET development that never seems to be included in ASP.NET is a recursive find control method. This problem results from the standard FindControl method on controls only searching within that control. It only finds child controls not grandchildren or anything farther down the line. This means that anything nested within other controls is a pain to access.

This limitation of the standard FindControl is annoying and has prompted me as well as many other people to use homegrown FindControl methods to solve this problem. This is a big problem when trying to programmatically access controls within templates. So earlier today I read on a list someone having trouble with the built-in find control, and it made me thing that a recursive find control would make a great extension method since it is a method plenty of people want to see on the control class anyway. So I went and wrote this simple little extension method.

For this nifty example I'll use this as my Page class. I've nested some Panels here to make sure that a standard find control would not work.

<form id="form1" runat="server">
<div>
    <asp:Panel ID="Panel1" runat="server">
        <asp:Panel ID="Panel2" runat="server">
            <asp:Panel ID="Panel3" runat="server">
                <asp:Panel ID="Panel4" runat="server">
                    <asp:Panel ID="Panel5" runat="server">
                        <asp:Label ID="ControlToFind" runat="server" />
                    </asp:Panel>
                </asp:Panel>
            </asp:Panel>
        </asp:Panel>
    </asp:Panel>
</div>
</form>

Now you'll see here in the code behind I am calling my recursive find control extension method. Notice that I am checking for null afterwards. This is because if I do not find the control my method returns null, so I should check for this. Also because I am using the as statement if the control is not a label my variable will also be null.

protected void Page_Load(object sender, EventArgs e)
{
    Label theLabel = form1.FindControlR("ControlToFind") as Label;
    if (theLabel != null)
    {
        theLabel.Text = "Found it!";
    }
}

Here is the code which makes this cool extension method possible.

public static class Extensions
{
    /// <summary>
    /// Searches recursively in this control to find a control with the name specified.
    /// </summary>
    /// <param name="root">The Control in which to begin searching.</param>
    /// <param name="id">The ID of the control to be found.</param>
    /// <returns>The control if it is found or null if it is not.</returns>
    public static Control FindControlR(this Control root, string id)
    {
        System.Web.UI.Control controlFound; 
        if (root != null) 
        { 
            controlFound = root.FindControl(id);
            if (controlFound != null)
            {
                return controlFound;
            }
            foreach (Control c in root.Controls) 
            {
                controlFound = c.FindControlR(id);
                if (controlFound != null)
                {
                    return controlFound;
                }
            } 
        } 
        return null;
    }
}

To create an extension method all I need to do is create a static method in a static class and pass as a parameter "this Type name" where Type and name are the type we wish to extend and name is a local variable name for the instance with which we wish to interact.

One thing I don't see in many examples of extension methods which I have used here is passing a parameter in the extension method. It really is this simple to pass the extra parameter.

This syntax reminds me a lot of the python language whose non-static class methods accept "this" as a parameter. It defines them as taking the instance as a parameter.

Have a great day!

Linking to the "I'm Feeling Lucky" Google Search

So one thing I've always loved about Google is the I'm feeling lucky search feature. Most of the time I know that the top result is the one I need. Earlier today, I was googling for how to link directly to the Google results using an "I'm Feeling Lucky" search, and I found one interesting thing. I am not sure how accurate the information is, but it seems that Google loses $110 million per year because of the "I'm feeling lucky" button. Clicking the button means you see no ads from Google, so Google effectively does not get any money from a user who clicks that button.

OK, so by now I would hope that someone is wondering why I would want to create a link which points to an "I'm Feeling Lucky" result. Well it is quite obvious that I want to hide the eventual destination of the link. I am assuming that people will notice that it goes to Google, but will not notice the part of the query string where it really doesn't send them to Google.

So I found out that all you have to add into the querystring is btnI=745. Yes, it is that easy, so Here is a nice example of a link I believe you should all see.

http://www.google.com/search?hl=en&q=french+military+victories&btnI=745

Google-FrenchMilitary

Following the link I have listed above is the same as doing what my screen shot illustrates.

Yes, I think it is a very funny joke. That site has been the top result on Google for that search for a looong time. It is the top result for "french military victories", and is quite a funny result. It could use an update to look like the current version of the Google results page, but it is still pretty nice. I could also link to this site, and send people through Google to get there.

Orcs Goblins and .NET

Have a great day, and don't use this for anything nefarious!

Watch TV Shows on Hulu

Not sure if everyone new about this. I would argue it is not off topic since it is an interesting thing on the web. Hulu is a great new service for watching television shows online anytime. Commercials are short and quick. It is an amazing service I expect plenty of people to start using. I've watched a few shows on there already.

Hulu-Home

I've found the interface quite easy to use and understand. Nothing seems weird or difficult. So when you go to watch a show you might get a message like this before the show starts.

Hulu-AdsQuestion

OK, cool. I can either watch one movie trailer at the beginning or I can have some commercial breaks. Not too shabby. If the movie trailer sounds interesting I will watch it, and if not I'll take the commercials. Trust me the commercials are not bad at all. There are not too many of them, and they are quite short compared to standard television commercial breaks.

Hulu-Commercials

This example I have here is a 1:26 runtime, so that is not too many commercial breaks. Plus, you can see when they are coming . This is a two hour long episode on television, so as you can imagine there are normally more and longer breaks. I've been very impressed with how quickly I can skip to any point in the show and watch. I've never had it lag on me, and it has never given me any loading screens or pinwheels that I often receive from other sites. Not sure how they got everything to stream so quickly and nicely, but you can be sure I will be watching on here a lot now.

If you have not looked at Hulu yet, you really need to. It is an amazing service, and it is free.

SQL Server Client Tools Installation

A while back I blogged about how to install sql server management studio, and it got a reasonable amount of feedback. More recently, Steve Smith posted a response to it where he highlights a better way of installing Management Studio. The method I outlined doesn't seem to work in every instance, so in his response Steve supplied a method which works more often.

The Solution: Run the SqlRun_Tools.msi file found in this folder.

{drive}\ENGLISH\SQL2005\DEVELOPER\SQL Server x86\Tools\Setup\SqlRun_Tools.msi

{drive}\ENGLISH\SQL2005\DEVELOPER\SQL Server x64\Tools\Setup\SqlRun_Tools.msi

Choose the top one for 32-bit systems and the bottom on for 64.

Lots of people keep UAC disabled on Windows, so they'll miss out on nice annoyances like the fact that this method requires you run the msi file as a local administrator. So as I am apt to do, I tried right clicking on it to choose the "Run As Administrator" context menu item. To my surprise it is not there! Below I've supplied the workaround I use in Vista for running as administrator when the context menu item is not present.

One of many ways around running a program as administrator when the context menu item is not present.

  1. In the start menu type "cmd".
  2. When the dos prompt icon is the only remaining icon right click on it and run as administrator.
  3. Copy the file location of the file you wish to run.
  4. Paste the location into the command prompt window.
  5. Click enter.
  6. Watch the program begin with administrator privileges.
  7. Celebrate and enjoy!

Update (9/9/2008): If the software claims that you have nothing to install when you run the SqlRun_Tools.msi then it means that installation has been borked. You will want to try running the Microsoft Installation Cleanup Utility. It will remove the client tools that SqlServer thinks are there, and it will then let you install them.

Windows Vista DreamScene Only Works with 1 Monitor

So I haven't had a lot of problems with Vista. There have been some slight issues including this one I blogged about recently. I think windows DreamScene is very cool, but I of course of more than one monitor attached to my computer. Okay, I can understand that they might have difficulty displaying the DreamScene video on both monitors, but not even allowing it to run because I have my desktop extended is absurd.

I would just like to be able to display it on the primary monitor or something. Perhaps let me pick a monitor and tell me only 1 monitor is allowed. instead of saying that I can't use it at all. I had to disable my second monitor to get DreamScene running.

If DreamScene and a second monitor are enabled at the same time, you'll see this nice popup from Windows.

DreamSceneErrorPopup

And when you click to see more information, it gives you this nice error message.

DreamSceneErrorMessage

Thanks guys.

How hard would it be to make DreamScene only run on 1 of the 2 monitors? Honestly here. let me choose a solid color background color even for the extra monitor(s).

One other request that gripes me a bit. I have plenty of backgrounds I like. I use a Gadget which changes my desktop background at a regular interval, but I wish this were a built in feature of windows. It really shouldn't be that hard, and it is certainly easier than DreamScene.

Have a great day!

Vista 64 Install Requires a DVD Device Driver

So I've been using Vista 32 for a while now. I've not had much trouble with it. I've not seen the horrors about which others speak. Perhaps now my eyes have opened a little bit to some of the problems. So while installing Windows Vista 64 on a machine, the installer said it needed a driver for the CD/DVD device. So at this point I am a bit confused. It makes no sense. If it could boot from the disc why can't it install from the disc. It can read the disc perfectly well. How else could it have booted from the disc?

After scouring a few forums trying to find the answer, I found a few interesting suggestions. While on 3rd party sites, I got suggestions of buying new devices or installing drivers in windows. Some suggestions of getting the drivers loaded during installation. On Microsoft forums I saw a lot of comments saying, "tell company x to write drivers for 64 bit". OK, thanks guys. It is an optical disc drive, and any OS installer should be able to boot pretty much any optical drive with minimal compatibility and install.

I eventually found one suggestion which seemed a bit crazy, "Change the IDE settings". So I figured I would try rewiring the device and see what happened. As it turned out for me if the drive was not set as the secondary slave, Vista 64 would not install. Just try and tell me that doesn't seem crazy.

The Solution that worked for me: Change the IDE settings so that the DVD Drive is the Secondary Slave.

Enjoy Windows Vista 64.