Posts
114
Comments
127
Trackbacks
10
July 2007 Entries
System.Web.UI.Control "FindControl" method using Generics

I'm currently supporting an ASP.NET project that has a lot of code like this using the System.Web.UI.Control.FindControl method to get data from child controls - in this example, from DataListItems belonging to a DataList control:

 
    foreach (DataListItem item in employeeDataList.Items)
    {
        if (item.ItemType == ListItemType.Item ||
            item.ItemType == ListItemType.AlternatingItem)
        {
            if (((HtmlInputCheckBox)item.FindControl("SelectionCheckBox")).Checked)
            {
                string positionId = ((Label)item.FindControl("PositionIdLabel")).Text;
                string personnelId = ((Label)item.FindControl("PersonnelIdLabel")).Text;
                ProcessPosition(positionId, personnelId);
            }
        }
    }

 

There's much room for improvement, but I started by adding a couple of FindControl overrides to the base class inherited by the project's pages.

The first calls the passed "parent" control's FindControl method, and throws an System.ArgumentOutOfRangeException if the specified ID is not found. This way, instead of just failing when later trying to use a null object, we know exactly which ID wasn't found in which "parent" control:

 

    protected Control FindControl(Control parentControl, string id)
    {
        Control control = parentControl.FindControl(id);

        if (control == null)
        {
            throw new ArgumentOutOfRangeException(
                string.Format("{0}.FindControl failed for ID \"{1}\"",
                parentControl.ID, id));
        }

        return control;
    }

 

The second uses generics to call the override shown above and cast the found Control to the specified Control type (the "where T : Control " constraint allows it to return only types that inherit from System.Web.UI.Control).

 

    protected T FindControl<T>(Control parentControl, string id) where T : Control
    {
        return (T)FindControl(parentControl, id);
    } 

 

Here's the code shown in the first example, modified to use the generic FindControl method. I think it's a little more readable than the original:

 

    foreach (DataListItem item in employeeDataList.Items)
    {
        if (item.ItemType == ListItemType.Item ||
            item.ItemType == ListItemType.AlternatingItem)
        {
            if (FindControl<HtmlInputCheckBox>(item, "SelectionCheckBox").Checked)
            {
                string positionId = FindControl<Label>(item, "PositionIdLabel").Text;
                string personnelId = FindControl<Label>(item, "PersonnelIdLabel").Text;
                ProcessPosition(positionId, personnelId);
            }
        }
    } 
Posted On Tuesday, July 17, 2007 11:18 PM | Comments (0)
How Right-Thinking Americans Should Pronounce "Agile"

On the anniversary of our nation's independence I call upon my U.S. citizens to throw off the shackles of our British oppressors and pronounce the word "agile" like true Americans:

  • The pretentious un-American "goofus" pronunciation: aj-ahyl
  • The right-thinking American "gallant" pronunciation: aj-uhl

Listening to the .NET Rocks Team System panel discussion from Tech Ed last week, I was dismayed to hear that only one of the six panelists pronounced "agile" like an American. I'm not sure which one it was, but it may have been the Canadian guy! (Yes, I realize that Canadians and everyone else from North, Central and South American are also American and it's arrogant to use that term only for people from the U.S., but I don't think that "United Statesian" will ever catch on. But enough aboot that, as they say in Canada.)

All of the dictionaries I've checked, including, ahem, the American Heritage dictionary, show "aj-uhl" as the preferred pronunciation.

According to the history of the agile manifesto at agilemanifesto.org, the only objection among the agile founding fathers to the term "agile" came from Martin Fowler, who said that most Americans don't know how to pronounce the word properly. I think that's why a lot of developers say "aj-ahyl" - they want to be like Martin. Being Fowleresque is a very admirable thing if you're designing software, but you don't have to talk like the guy if you're not British.

Am I making too big a deal of this? Perhaps, but it's a slippery slope, my friends. Start saying "aj-ahyl", and before you know it you'll be adding an extra syllable to "aluminum", driving on the wrong side of the road, and clamoring for the addition of a System.Drawing.Colour namespace. Think it can't happen here? Think again - One of the guys on the .NET Rocks show pronounced "process" with a long O, like Jean-Luc-Freaking Picard!

P.S.

Please don't respond with nasty comments - My sense of self-esteem is very fraj-ahyl.

Posted On Wednesday, July 4, 2007 10:41 AM | Comments (6)
Free "Mini-Refactor!" From Developer Express

When a free download of Refactor!™ for ASP.NET 2.2 was announced in May by Developer Express, I bookmarked it for future reference because I wasn't working on an ASP project at the time.

When I took another look, I realized that the download includes 19 C#/VB code refactorings that work in any project, ASP.NET or not. They work in Visual Studio 2003, VS2005, and "Orcas".

Included are Refactor! versions (with much nicer user interfaces) of four of the seven built-in VS2005 C# refactorings:

  • Rename
  • Extract Method
  • Encapsulate Field
  • Reorder Parameters

...plus:

  • Create Overload:
    Creates an overload to an existing method, with fewer parameters.
  • Extract Property:
    Creates a new property from the selected code block. The selection is replaced with appropriate code to reference the newly-declared property.
  • Flatten Conditional:
    Unindents the If or Else statement for a conditional and applies one of the following refactorings: Replace Nested Conditional with Guard Clause, Remove Redundant Else, or Reverse Conditional followed by Remove Redundant Else.
  • Inline Temp:
    Replaces all references to a local variable with its initial value.
  • Introduce Constant:
    Declares a new constant, initialized to the value of the selected string or number.
  • Introduce Local:
    Creates a new local variable initialized to the selected expression. Replaces the selection with the new variable.
  • Move Declaration Near Reference:
    Moves the declaration statement for a local variable near its first reference.
  • Move Initialization to Declaration:
    Combines a local variable's declaration with its first initialization.
  • Replace Temp with Query:
    Replaces each reference to the active local variable with a call to an extracted method, which returns the initial value assigned to the local.
  • Reverse Conditional:
    Inverts the logic in a conditional statement and swaps the If and Else blocks.
  • Safe Rename:
    Safely renames non-private methods and properties by creating a duplicate member to preserve the old signature, calling the renamed member from the old member. The old member is hidden from Intellisense and marked "Obsolete". References to the old member will generate compiler warnings directing developers to the new renamed member.
  • Simplify Expression:
    Resolves an expression to its simplest form.
  • Split Initialization from Declaration:
    Breaks an initialized declaration for a local variable into a declaration and a separate initialization statement.
  • Split Temporary Variable:
    Splits a local variable which has too many assignments, declaring a new local at the first new assignment following the first reference.

...and the 10 ASP.NET 2.0 refactorings:

  • Add Validator:
    Adds one or more selected Validators to the active input control.
  • Extract ContentPlaceHolder:
    Moves the selected content from a .master page to a new .aspx file, placing it inside <asp:content> tags, and inserts a new <asp:contentplaceholder> tag at the extraction point inside the master page.
  • Extract ContentPlaceHolder (and create master page):
    Moves the content that is *outside* of the selection (in the active .aspx page) to a new master page, inserting a <asp:contentplaceholder> tag to reference the extracted content, and then wraps the selection in the aspx page with <asp:content> tags and adds a MasterPageFile attribute to link to the new master page.
  • Extract Style (Class):
    Converts an inline style to a named class style.
  • Extract Style (id):
    Converts an inline style to a named id style.
  • Extract to UserControl:
    Creates a UserControl for the selected block including content and dependent code.
  • Move Style Attributes to CSS:
    Moves styling attributes from the active control to a new CSS class and applies the class to the control.
  • Move to Code-behind:
    Moves code located in <script> tags to the code-behind file.
  • Rename Style:
    Renames the active CSS style and updates all references to that style.
  • Surround with Update Panel:
    Surrounds a contiguous block of text in the source view with <asp:UpdatePanel …> and <ContentTemplate> tags.

Here's a link to a post by Mark Miller, mad genius of Developer Express, showing examples of all of the refactorings.

Posted On Wednesday, July 4, 2007 8:51 AM | Comments (0)
Tag Cloud