none
Marcar los CheckBox de un ListView a través de un CheckBox extra C# RRS feed

  • Pregunta

  • Tengo un formulario en el cual tengo los siguientes componentes.

    CheckBox llamado "chbRole".

    ListView llanado "lstvRoles".

    Botón Eliminar llamado "btnDelRole".

    Label llamado "lblRoles".

    El ListView contiene Items que se obtienen a través de una base de datos en SqlServer con la siguiente información:

    RoleID | Nombre | Descripción

    Los Items del ListView contienen CheckBox y el botón btnDelRole elimina aquellos Items marcados con el CheckBox.

    Lo que quiero lograr es que, por medio del CheckBox chbRole marcar o desmarcar todos los CheckBox de los Items del ListView lstvRoles.

    Tengo los siguientes métodos que intervienen en esta tarea:

    private void chbRole_CheckedChanged(object sender, EventArgs e) {
        checks(lstvRoles, chbRole.Checked);
    }
    
    private void checks(ListView lv, Boolean ch) {
        foreach(ListViewItem item in lv.Items)
            item.Checked = ch;
    }
    
    private void lstvRoles_ItemChecked(Object sender, ItemCheckedEventArgs e) {
        lblRoles.Text = "Roles " + lstvRoles.CheckedItems.Count;
        btnDelRole.Enabled = lstvRoles.CheckedItems.Count == 0 ? false : true;
        chbRole.Checked = lstvRoles.CheckedItems.Count == lstvRoles.Items.Count ? true : false; // ERROR
    }

    Si elimino la tercera instrucción (marcada con comentario ERROR) del evento ItemChecked para el ListView lstvRoles, todo funciona bien.

    Pero quiero que al marcar todos los CheckBox del ListView se marque el CheckBox chbRole, y si no están marcados todos (4 de 5, p.e.) se desmarque sólo chbRole.

    Con el código que tengo funciona a medias. Al presionar chbRole se marcan 4 Items y al presionar de nuevo se marcan los 5. En resumen: primer clic, marca 4; segundo clic, marca 5, tercer clic, desmarca todo.

    Si marco cada Item individualmente al marcar el 5to, se marca chbRole, al desmarcar sólo 1 Item, se desmarca chbRole y por ende, todos los items también se desmarcan, porque se llama el evento CheckedChanged de chbRole.

    Espero haber sido claro.

    jueves, 31 de marzo de 2016 2:11

Todas las respuestas

  • Necesita una variable de control declarada a nivel de formulario para evitar enciclarse, que imagino que es su problema.  Por cierto, decir "error" y no mostrar exactamente cuál es el error no es útil.  Siempre muestre el error.

    //Variable a nivel de formulario.
    private int _dontLoop = 0;
    
    private void chbRole_Checked(object sender, EventArgs e)
    {
        if (_dontLoop > 0) return;
        ++_dontLoop;
        checks(lstvRoles, chbRole.Checked);
        --_dontLoop;
    }
    
    private void lstvRoles_ItemChecked(object sender, ItemCheckedEventArgs e)
    {
        lblRoles.Text = "Roles" + lstvRoles.CheckedItems.Count;
        btnDelRole.Enabled = lstvRoles.CheckedItems.Count > 0;
        if (_dontLoop > 0) return;
        ++_dontLoop;
        chbRole.Checked = lstvRoles.CheckedItems.Count == lstvRoles.Items.Count;
        --_dontLoop;
    }


    Jose R. MCP
    Code Samples


    jueves, 31 de marzo de 2016 14:28
    Moderador