¿Cómo crear y usar programáticamente una lista de casillas de verificación de ASP.NET?

votos
4

Tengo una página con una tabla de cosas y debo permitir que el usuario seleccione las filas para procesar. He descubierto cómo agregar una columna de casillas de verificación a la tabla, pero parece que no puedo averiguar cómo comprobar si están marcadas cuando se envía el formulario. Si fueran elementos estáticos, podría simplemente verificarlo, this.theCheckBoxpero están generados programáticamente.

Además, no estoy muy contento con la forma en que estoy adjuntando mis datos a ellos (rellenándolo en la propiedad ID).

No estoy seguro de si es relevante, pero estoy buscando un catch-22, ya que necesito saber cuáles de las casillas de verificación que se crearon la última vez se verificaron antes de poder volver a ejecutar el código que las creó.


Editar: he encontrado una solución casi. Al establecer la AutoPostBackpropiedad y el CheckedChangedevento:

checkbox.AutoPostBack = false;
checkbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);

Puedo hacer que se llame al código en una publicación posterior para cualquier casilla de verificación que haya cambiado. Sin embargo, esto tiene dos problemas:

  • La devolución de llamada se procesa después de (o durante, no estoy seguro) Page_Loaddonde necesito usar esta información
  • No se solicita la devolución de llamada para las casillas de verificación que se verificaron cuando la página se cargó y todavía están.

Editar 2:

Lo que terminé haciendo fue etiquetar todas mis identificaciones con un prefijo conocido y rellenar esto en la parte superior de Form_Load:

foreach (string v in this.Request.Form.AllKeys)
{
    if (v.StartsWith(Prefix))
    {
        var data = v.Substring(Prefix.Length);
    }
}

todo lo demás parece llegar tarde.

Publicado el 24/07/2009 a las 23:16
fuente por usuario
En otros idiomas...                            


7 respuestas

votos
1

En primer lugar, asegúrese de que cada casilla de verificación tenga una identificación y de que tenga el servidor "runat =" "" en la etiqueta.

luego use la función FindControl () para encontrarlo.

Por ejemplo, si está recorriendo todas las filas en un GridView ...

foreach(GridViewRow r in Gridview1.Rows)
{

    object cb = r.FindControl("MyCheckBoxId");
    if(r != null)
    {
      CheckBox chk = (CheckBox)cb;
      bool IsChecked = chk.Checked;
    }

}
Respondida el 24/07/2009 a las 23:44
fuente por usuario

votos
2

Voy a suponer que estás utilizando una DataList, pero esto debería funcionar con Control y que se puede modelar. También voy a suponer que estás usando DataBinding.

Frente del código:

<asp:DataList ID="List" OnItemDataBound="List_ItemDataBound" runat="server">
    <ItemTemplate>
        <asp:CheckBox ID="DeleteMe" runat="server"/>
        <a href="<%# DataBinder.Eval(Container, "DataItem.Url")%>" target="_blank">
            <%# DataBinder.Eval(Container, "DataItem.Title")%></a>
    </ItemTemplate>
</asp:DataList>
<asp:Button ID="DeleteListItem" runat="server" OnClick="DeleteListItem_Click" ></asp:Button>

Código detrás:

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadList();
    }

    protected void DeleteListItem_Click(object sender, EventArgs e)
    {
        foreach (DataListItem li in List.Items)
        {
            CheckBox delMe = (CheckBox)li.FindControl("DeleteMe");

            if (delMe != null && delMe.Checked)
                    //Do Something
            }
        }

        LoadList();
    }

    protected void LoadList()
    {
        DataTable dt = //Something...
        List.DataSource = dt;
        List.DataBind();
    }

    protected void List_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
        {
            string id = DataBinder.Eval(e.Item.DataItem, "ID").ToString();
            CheckBox delMe = (CheckBox)e.Item.FindControl("DeleteMe");

            if (delMe != null)
                delMe.Attributes.Add("value", id);                
        }
    }
}
Respondida el 25/07/2009 a las 00:56
fuente por usuario

votos
0

Tu publicación es un poco vaga Ayudaría ver cómo está agregando controles a la mesa. ¿Es un ASP: tabla o una tabla HTML normal (presumiblemente con un atributo runat = "server" ya que le ha agregado elementos con éxito)?

Si tiene la intención de dejar que el usuario haga varias selecciones, presione el botón "Enviar", luego de lo cual procesará cada fila según la fila que esté marcada, entonces no debería manejar el evento CheckChanged. De lo contrario, como habrás notado, estarás causando una devolución de datos cada vez y no procesará ninguna de las otras casillas de verificación. Por lo tanto, cuando crea el CheckBox, no configure el manejador de eventos para que no cause una devolución de datos.

En el manejador de eventos del botón Enviar, recorrerá cada fila de la tabla, celda, y luego determinará si el control secundario de la celda contiene una casilla de verificación.

Sugeriría no usar una tabla. De lo que está describiendo tal vez una GridView o DataList es una mejor opción.


EDITAR: aquí hay un ejemplo simple para demostrar. Debería poder hacer que esto funcione en un nuevo proyecto para probar.

Margen

    <form id="form1" runat="server">
    <div>
    <table id="tbl" runat="server"></table>
    <asp:Button ID="btnSubmit" runat="server" Text="Submit"
      onclick="btnSubmit_Click" />
    </div>
    </form>

Código detrás

protected void Page_Load(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        var row = new HtmlTableRow();
        var cell = new HtmlTableCell();
        cell.InnerText = "Row: " + i.ToString();
        row.Cells.Add(cell);
        cell = new HtmlTableCell();
        CheckBox chk = new CheckBox() { ID = "chk" + i.ToString() };
        cell.Controls.Add(chk);
        row.Cells.Add(cell);
        tbl.Rows.Add(row);
    }
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
    foreach (HtmlTableRow row in tbl.Rows)
    {
        foreach (HtmlTableCell cell in row.Cells)
        {
            foreach (Control c in cell.Controls)
            {
                if (c is CheckBox)
                {
                    // do your processing here
                    CheckBox chk = c as CheckBox;
                    if (chk.Checked)
                    {
                        Response.Write(chk.ID + " was checked <br />");
                    }
                }
            }
        }
    }
}
Respondida el 25/07/2009 a las 00:58
fuente por usuario

votos
1

Los datos de devolución se restauran entre el evento InitComplete y el evento PreLoad. Si las casillas de verificación no se crean hasta más tarde, las casillas de verificación reproducirán sus eventos y los datos se cargarán en el control poco después de su creación.
Si esto es demasiado tarde para ti, entonces tendrás que hacer algo como lo que ya estás haciendo. Es decir, tendrá que acceder a los datos de la publicación antes de que se le otorgue el control.
Si puedes guardar el UniqueIdde cadaCheckBoxque crees puede acceder directamente a los datos de la publicación sin tener que darles un prefijo especial. Puede hacer esto creando una lista de cadenas en las que guarda los identificadores a medida que los genera y luego los guarda en el estado de vista. Por supuesto, eso requiere que el estado de vista esté habilitado y ocupe más espacio en viewstate.

foreach (string uniqueId in UniqueIds)
{
    bool data = Convert.ToBoolean(Request.Form[uniqueId]);
    //...
}
Respondida el 27/07/2009 a las 21:56
fuente por usuario

votos
0

¿Qué pasa con el uso del control CheckBoxList ? No tengo Visual Studio abierto ahora, pero, por lo que recuerdo, es un control DataBound que proporciona DataSourcey DataBind()en el que puede proporcionar una lista en tiempo de ejecución. Cuando la página hace una devolución de datos, puede recorrer la lista llamando algo así como myCheckBoxList.Itemsy verificar si el elemento actual se selecciona mediante el ListItem.Selectedmétodo de llamada . Esto debería funcionar.

Respondida el 27/07/2009 a las 22:03
fuente por usuario

votos
0

Agréguelos en una anulación del método CreateChildControls de la página. ¡Asegúrate de darles una identificación! De esta forma, se agregan al árbol de control en el momento correcto.

En mi humilde opinión, la mejor manera sería utilizar DataBound Templated Control , es decir, algo así como un ListView (en .NET 3.5). luego en la carga de la página después de la postback atraviesa todos los elementos en el control de datos y utiliza el elemento. Encuentra el control para obtener la casilla de verificación real.

Respondida el 27/07/2009 a las 22:03
fuente por usuario

votos
0

Lo que terminé haciendo fue etiquetar todas mis identificaciones con un prefijo conocido y rellenar esto en la parte superior de Form_Load:

foreach (string v in this.Request.Form.AllKeys)
{
    if (v.StartsWith(Prefix))
    {
        var data = v.Substring(Prefix.Length);
    }
}

todo lo demás parece llegar tarde.

Respondida el 23/08/2009 a las 23:05
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more