2009-05-18 9 views
25

Est-il possible de DataBind une CheckBoxList ASP.NET de sorte qu'une valeur de chaîne dans les données devient l'étiquette de la case à cocher et une valeur boolique vérifie/décoche la case?ASP.NET CheckBoxList DataBinding Question

Sur mon Webform asp.net j'ai un CheckBoxList comme ceci:

<asp:CheckBoxList runat="server" ID="chkListRoles" DataTextField="UserName" DataValueField="InRole" /> 

Dans le code derrière j'ai ce code:

var usersInRole = new List<UserInRole> 
{ 
    new UserInRole { UserName = "Frank", InRole = false}, 
    new UserInRole{UserName = "Linda", InRole = true}, 
    new UserInRole{UserName = "James", InRole = true}, 
}; 

chkListRoles.DataSource = usersInRole; 
chkListRoles.DataBind(); 

J'espérais un peu que les cases à cocher seraient vérifié lorsque InRole = true. J'ai aussi essayé InRole = "Vérifié". Les résultats étaient les mêmes. Je n'arrive pas à trouver un moyen de DataBind et les cases à cocher sont automatiquement cochées/décochées.

Actuellement, je résous le problème en définissant selected = true pour les éléments appropriés dans l'événement DataBound. On dirait qu'il y a une solution plus propre à portée de main.

Merci Vous

+0

http://stackoverflow.com/questions/879434/asp-net-checkboxlist-databinding-question –

Répondre

37

EDIT: Il n'existe aucun moyen de le faire via le balisage. DataValueField ne détermine pas si l'élément de case à cocher est activé ou non. Il récupère ou stocke la valeur à utiliser dans les publications. Le DataValueField est commun à travers CheckBoxLists, RadioButtonLists, ListControl, etc.

Il s'agit de la seule façon de présélectionner les cases comme vous l'avez déjà découvert.

chkListRoles.DataSource = usersInRole; 
chkListRoles.DataBind(); 

foreach(ListItem item in chkListRoles.Items) 
item.Selected = usersInRole.Find(u => u.UserName == item.Text).InRole; 
+0

Merci Jose, votre réponse clarifie la situation. –

+3

Merci aussi de moi José, je vais utiliser ce lambda ;-) –

+2

Cela ressemble à une omission étrange dans ASP.NET. Pourquoi n'ont-ils pas aussi un attribut DataCheckedField? –

0

Je pense que vous auriez à dire le contrôle ce que la propriété de se lier à ... dans ce cas « InRole ».

Je ai joué avec et il semble qu'il n'y a plus à se lier à la sélection de la case, vous devez le faire vous-même. J'ai été en mesure de me lier au texte et aux valeurs de la liste de contrôle qui ne semblent traiter que de l'étiquette de chaque case de la liste.

+0

Dans le fichier * .aspx, je déclare CheckBoxList avec l'attribut DataValueField = "InRole". C'est ce que tu veux dire? –

+0

C'est ce dont je parlais ... Je n'ai pas fait défiler pour voir que vous aviez défini cela dans le code de l'interface utilisateur ... pardon. – CSharpAtl

+0

Fait est que souvent la valeur est utilisée pour faire un traitement ultérieur. – Younes

9

J'ai fait un contrôle personnalisé pour cela, après avoir fatigué de la OnItemDataBound liaison d'. Il vous permettra de lier l'attribut Selected. Vous pouvez facilement faire le même contrôle pour RadioButtonList en changeant ce dont le contrôle personnalisé dérive. Pour l'utiliser, ajoutez simplement l'attribut DataCheckedField lorsque vous créez le contrôle dans votre balisage. N'oubliez pas de référencer les contrôles personnalisés dans votre fichier web.config.

Markup

<myControls:SimpleCheckBoxList runat="server" ID="chkListRoles" 
           DataCheckedField="InRole" 
           DataTextField="UserName" 
           DataValueField="UserId" /> 

Code pour le contrôle

public class SimpleCheckBoxList : System.Web.UI.WebControls.CheckBoxList 
{ 
    public string DataCheckedField 
    { 
     get 
     { 
      string s = (string)ViewState["DataCheckedField"]; 
      return (s == null) ? String.Empty : s; 
     } 
     set 
     { 
      ViewState["DataCheckedField"] = value; 
      if (Initialized) 
       OnDataPropertyChanged(); 
     } 
    } 

    protected override void PerformDataBinding(IEnumerable dataSource) 
    { 
     if (dataSource != null) 
     { 
      if (!this.AppendDataBoundItems) 
       this.Items.Clear(); 

      if (dataSource is ICollection) 
       this.Items.Capacity = (dataSource as ICollection).Count + this.Items.Count; 

      foreach (object dataItem in dataSource) 
      { 
       ListItem item = new ListItem() 
       { 
        Text = DataBinder.GetPropertyValue(dataItem, DataTextField).ToString(), 
        Value = DataBinder.GetPropertyValue(dataItem, DataValueField).ToString(), 
        Selected = (DataCheckedField.Length > 0) ? (bool)DataBinder.GetPropertyValue(dataItem, DataCheckedField) : false 
       }; 
       this.Items.Add(item); 
      } 
     } 
    } 
} 
+0

Cela semble intéressant, mais 'dataSelectedField' montre une erreur. Aucune suggestion? – MAW74656

+0

@ MAW74656 Essayez plutôt de le remplacer par 'dataCheckedField'. On dirait une faute de frappe de trois ans. S'il vous plaît donner votre avis sur vos résultats! – sshow

5

Il est impossible en utilisant le balisage. Qu'est-ce que vous pouvez faire est de lier la checkboxlist comme vous le vouliez travailler - avec le bool dans le DataValueField, puis simplement ajouter cela en tant qu'événement OnDataBound.

protected void myCheckBoxList_DataBound(object sender, EventArgs e) 
    { 
     foreach (ListItem item in myCheckBoxList.Items) 
     { 
      item.Selected = bool.Parse(item.Value); 
     } 
    } 

La différence entre cette solution et celle proposée par José Basilio est que celui-ci fonctionne avec toutes sortes de méthodes de liaison de données.Par exemple liaison avec un SelectMethod en utilisant la nouvelle fonctionnalité ModelBinding dans la version 4.5.

+0

Oui, cette solution fonctionne pour .NET v4.5 alors que la précédente ne fonctionne pas. – Jony