Asignar un botón por defecto

Seguro que todos hemos pasado por el típico problema en nuestros inicios con ASP.NET, y es que si tenemos varios botones en una misma página, cada uno con su acción determinada, cuando el cliente presiona return ni tal siquiera sabemos qué acción se va a realizar.

Pongamos un ejemplo sencillito. Imaginemos que tenemos esta página:

DefaultButton.aspx
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
    <br />
    <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
    <asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
    <br />
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></div>


DefaultButton.aspx.cs
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = TextBox1.Text;
    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        Label1.Text = TextBox2.Text;
    }


Bajo este escenario, si el usuario se encuentra rellenando el TextBox2 y presiona enter, se ejecutará el evento Button1_Click, y no el Button2_Click como sería deseable, por lo que el texto de la Label1 pasaría a ser el contenido del Textbox1, y no el del TextBox2 que es el que el usuario quería.

ASP.NET nos ofrece la opción de asignar un botón por defecto a toda la página entera, si es que quisiéramos que siempre que un usuario apriete enter (esté donde esté), se ejecute el evento asociado a ese botón.
Esto se consigue asignando el botón en el propio tag del formulario:

    <form id="form1" runat="server" defaultbutton="Button1">

o dinámicamente mediante un simple:

    form1.DefaultButton = "Button2";

Sin embargo, aunque es bueno saber que es posible porque en otros escenarios puede ser útil, a nosotros no nos interesa porque lo que queremos es que:
- Si el usuario está en el TextBox1 y presiona enter, se ejecute el evento asociado al Button1.
- Si el usuario está en el TextBox2 y presiona enter, se ejecute el evento asociado al Button2.

Afortunadamente esto también es posible a la par que muy fácil. No hay más que agrupar cada TextBoxX - ButtonX en un Panel, y hacer uso del atributo "DefaultButton" de cada Panel. Es decir, nos quedaría algo como:

DefaultButton.aspx
        <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px" DefaultButton="Button1">
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
        </asp:Panel>
        <br />
        <asp:Panel ID="Panel2" runat="server" Height="50px" Width="125px" DefaultButton="Button2">
            <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
            <asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
        </asp:Panel>
        <br />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></div>


Obviamente, esto sirve tanto para un simple TextBox con un Button, como con una larga lista de TextBox, DropdownList, RadioButton, etc.

Como os podréis imaginar, todo esta también se puede hacer con javascript. Si queréis averiguar cómo, os recomiendo que le echéis un vistazo al artículo Insertar javascript dinámicamente y luego a Set Focus to an ASP.NET Control.

Ojo! Daos cuenta que en dicho artículo se utiliza Page.RegisterClientScriptBlock, algo que en ASP.NET 2.0 ya está "deprecated", por tanto os vuelvo a insistir en que leais el artículo Insertar javascript dinámicamente, donde se explica el nuevo modo de trabajar con javascript en ASP.NET.