2010-11-02 36 views
0

J'ai une grille de databound avec une colonne de champ modèle qui est une case à cocher. Lorsque l'utilisateur coche la case à cocher, il effectue un autopostback et met à jour la ligne pour indiquer l'état de vérification de la boîte. Ma première tentative consistait simplement à utiliser la méthode OnCheckedChanged, mais quand cela est appelé, je n'ai aucun moyen de savoir de quelle ligne provient la case à cocher. Ainsi, je ne sais pas quelle ligne mettre à jour.Détermination de la ligne de la grille à partir de la sélection de case à cocher modélisée avec autopostback

Quelqu'un peut-il suggérer une méthode pour déterminer quelle ligne provient de la case à cocher qui a déclenché l'événement oncheckedchanged? Ou pouvez-vous suggérer un meilleur moyen de réaliser ce que je dois faire?

Je ne peux pas lier la case à cocher à la colonne de données car je ne veux pas désactiver la case à cocher dans le mode de sélection et je ne souhaite pas que l'utilisateur passe en mode édition pour modifier la valeur. J'ai également besoin que toutes les lignes soient modifiables. Donc, le meilleur itinéraire semble être dans une colonne sur gabarit.

Répondre

1

Vous pouvez trouver la case à cocher cochée en itérant sur les lignes. Ce n'est pas aussi inefficace que cela en a l'air (quand le PageSize de la Grille n'est pas trop élevé).

Vous pouvez également obtenir le GridViewRow via Checkbox.Parent.Parent:

Protected Sub MyCheckBoxCheckedChanged(ByVal sender As Object, ByVal e As EventArgs) 
     Dim cb As CheckBox = DirectCast(sender, CheckBox) 
     Dim row As GridViewRow = DirectCast(cb.Parent.Parent, GridViewRow) 
     row.BackColor = DirectCast(IIf(cb.Checked, Color.Red, Color.White), Color) 
    End Sub 

C'est plus rapide que l'option 1 mais si vous F.E. imbrique la case à cocher dans une table à l'avenir, cela ne fonctionnerait plus sans ajustement.

Je préférerais normalement l'option 1, car dans un gestionnaire d'événements, une milliseconde plus ou moins importe peu.


Mise à jour: obtenir le GridViewRow via NamingContainer est un autre (à mon avis la meilleure) Option:

Dim row As GridViewRow = DirectCast(cb.NamingContainer, GridViewRow) 

Cela fonctionne même encore lorsque vous imbriquez la case à l'intérieur d'autres contrôles comme une table.

+0

Non, je ne veux pas trouver toutes les colonnes cochées. Je veux savoir quelle case a été cochée, et seulement mettre à jour cette ligne. –

+0

mis à jour, deux façons d'obtenir le GridViewRow de la case à cocher. –

+0

Bonne idée sur le parent, parent .. je vais essayer ça demain. Je suis d'accord avec @jwiscarson que cela semble hacky, cependant. Votre idée de vérifier si le contrôle de l'expéditeur = trouvé semble un peu inefficace, mais c'est aussi une bonne idée. –

0

Je ne pense pas qu'il existe un moyen de procéder comme indiqué sans gérer les événements RowEditing, RowUpdating et RowCancelingEdit.

Sinon, je vous suggère d'ajouter un CommandField au GridView, comme ceci:

<asp:CommandField ShowSelectButton="true" /> 

Vous aurez besoin de gérer la GridView.SelectedIndexChanging, encore une fois comme ceci:

void GridView_SelectedIndexChanging(object sender, GridViewSelectEventArgs e) 
    { 
     GridView.SelectedIndex = e.NewSelectedIndex; 
    } 

Une fois vous êtes dans SelectedIndexChanging, vous pouvez utiliser GridView.Rows[e.NewSelectedIndex].FindControl("id") pour obtenir le contrôle dont vous avez besoin - en supposant que cette fonctionnalité est toujours essentielle pour vous. Je viens de lire votre mise à jour, et je ne suis pas tout à fait sûr de ce que vous essayez d'atteindre ici. Il semble que vous connaissiez le CommandField. Que voulez-vous que votre site Web fasse lorsque vous cochez cette case qui doit être faite indépendamment des états de ligne?

Edit 2: Vous pouvez également jeter object sender à votre CheckBox, et trouver le GridRow approprié à l'aide .Parent(), mais cela a toujours senti très hacky pour moi.

Édition 3: Je jure, je vais arrêter d'éditer cela finalement.

Je n'ai jamais essayé cela, mais vous pourriez obtenir une référence à CheckBox.ClientID et essayer de passer par chaque ligne dans le GridView, et en appelant GridViewRow.FindControl(CheckBox.ClientID). Je n'ai vraiment aucune idée si cela fonctionnera, cependant.

+0

Pour répondre à votre question sur ce que j'essaie de réaliser ... la case à cocher indique que certaines entités de données sont "associées" au client actuel. En cliquant sur la case à cocher active cette association (qui tire réellement un grand nombre de sprocs pour raccorder toutes les données appropriées). Il peut y avoir plusieurs dizaines à quelques centaines de ces cases à cocher, de sorte que le client ne veut pas avoir à faire "sélectionner une ligne, entrer en mode édition, sélectionner une case à cocher, sélectionner une ligne de mise à jour" et cela serait très ennuyeux. Ils veulent simplement cliquer sur la case à cocher pour définir la valeur. –

+0

En ce qui concerne votre Edit 3, je ne sais pas comment trouver le contrôle est utile, puisque l'expéditeur est déjà un pointeur sur le contrôle. Je ne pense pas qu'il soit plus facile d'obtenir le datarow en utilisant le contrôle trouvé via FindControl(). –

+0

Err, désolé - Je pensais l'utiliser sur chacune des lignes dans le GridView, mais je ne l'ai pas spécifié correctement. Modification ... – jwiscarson