2009-05-18 19 views
25

¿Es posible DataBind una ASP.NET CheckBoxList tal que un valor de cadena en los datos se convierte en la etiqueta de la casilla de verificación y un valor bool marca/desmarca la casilla?ASP.NET CheckBoxList DataBinding Pregunta

En mi formulario web asp.net tengo un CheckBoxList así:

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

En el código detrás tengo este código:

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(); 

que estaba esperando un poco que las casillas serían marcado cuando InRole = verdadero. También probé InRole = "Checked". Los resultados fueron los mismos. Parece que no puedo encontrar una forma de DataBind y automágicamente tengo las casillas marcadas/desmarcadas.

Actualmente resuelvo el problema estableciendo selected = true para los elementos apropiados en el evento DataBound. Parece que hay una solución más limpia más allá de mi alcance.

Gracias

+0

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

Respuesta

37

EDITAR: No hay forma de hacerlo a través del marcado. DataValueField no determina si el elemento de casilla de verificación es o no verificable. Recupera o almacena el valor que se utilizará en las devoluciones. El DataValueField es común en CheckBoxLists, RadioButtonLists, ListControl, etc.

Esta es la única forma de preseleccionar las casillas de verificación como ya ha descubierto.

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

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

Gracias José, tu respuesta aclara la situación. –

+3

También gracias de mi parte José, usaré esa lambda ;-) –

+2

Parece una extraña omisión en ASP.NET. ¿Por qué no tienen también un atributo DataCheckedField? –

0

yo creo que tendría que decirle al control de los bienes que se una a ... en este caso "InRole".

Jugué con él y parece que no hay manera de vincularlo a la selección de la casilla de verificación, tiene que hacerlo usted mismo. Pude vincular el texto y los valores de la lista de verificación que solo parecen tratar con la etiqueta de cada casilla de verificación de la lista.

+0

En el archivo * .aspx declaro el CheckBoxList con el atributo DataValueField = "InRole". ¿Es eso lo que quieres decir? –

+0

Eso es de lo que estaba hablando ... No me desplacé para ver que lo habías establecido en el código de UI ... lo siento. – CSharpAtl

+0

El hecho es que a menudo el valor se utiliza para hacer cualquier procesamiento adicional. – Younes

9

me hizo un control personalizado para esto, después de cansarse de la unión al OnItemDataBound. Le permitirá vincular el atributo Selected. Puede hacer fácilmente el mismo control para RadioButtonList cambiando lo que deriva el control personalizado.

Para usar esto, simplemente agregue el atributo DataCheckedField cuando crea el control en su marcado. Recuerde hacer referencia a los controles personalizados en su archivo web.config.

marcado

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

código para el control

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

Parece interesante, pero 'dataSelectedField' muestra un error. ¿Alguna sugerencia? – MAW74656

+0

@ MAW74656 Trate de reemplazarlo con 'dataCheckedField' en su lugar. Parece un error tipográfico de tres años. Por favor, ¡den sus comentarios sobre sus resultados! – sshow

5

No es posible el uso de marcas. Lo que puede hacer es enlazar la lista de casillas de verificación como quería que funcione, con bool en DataValueField y luego simplemente agregar esto como evento OnDataBound.

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

La diferencia entre esta solución y el propuesto por José Basilio es que éste funciona con todo tipo de métodos de enlace de datos.Por ejemplo, vinculando con un método Select usando la nueva característica ModelBinding en v4.5.

+0

Sí, esta solución funciona para .NET v4.5 mientras que la anterior no. – Jony