2008-10-20 10 views
9

¿Qué tipo de colección debería usar para convertir la colección de NameValue enlazable con GridView? Al hacerlo directamente, no funcionó.Vincular NameValueCollection a GridView?

Código de aspx.cs

private void BindList(NameValueCollection nvpList) 
    { 
    resultGV.DataSource = list; 
    resultGV.DataBind(); 
    } 

Código de aspx

<asp:GridView ID="resultGV" runat="server" AutoGenerateColumns="False" Width="100%"> 
    <Columns> 
     <asp:BoundField DataField="Key" HeaderText="Key" /> 
     <asp:BoundField DataField="Value" HeaderText="Value" /> 
    </Columns> 
</asp:GridView> 

Cualquier consejo más bienvenido. Gracias. X.

Respuesta

8

Puede usar la cadena del diccionario <, cadena > en lugar de NameValueCollection. Desde Diccionario < T, T > implementa IEnumerable podría utilizar LINQ como tan:

resultGV.DataSource = from item in nvpDictionary 
         select new { Key = item.Key, Value = item.Value }; 
resultGV.DataBind(); 

[EDIT] En realidad, es posible que pueda utilizar directamente como diccionario:

resultGV.DataSource = nvpDictionary; 
resultGV.DataBind(); 

Si no se asigna clave/valor de la manera que desee, siempre puede volver a LINQ. LINQ también le permite cambiar el nombre de los campos a lo que desee.

[EDITAR] Si no puede cambiar para usar el diccionario < T, T >, haga una copia de NameValueCollection como un diccionario en el método y agréguelo a él.

private void BindList(NameValueCollection nvpList) 
{ 
    Dictionary<string,string> temp = new Dictionary<string,string>(); 
    foreach (string key in nvpList) 
    { 
     temp.Add(key,nvpList[key]); 
    } 

    resultGV.DataSource = temp; 
    resultGV.DataBind(); 
} 

Si hace esto mucho, podría escribir un método de extensión para convertir a un diccionario y usarlo.

public static class NameValueCollectionExtensions 
{ 
    public static Dictionary<string,string> ToDictionary(this NameValueCollection collection) 
    { 
     Dictionary<string,string> temp = new Dictionary<string,string>(); 
     foreach (string key in collection) 
     { 
      temp.Add(key,collection[key]); 
     } 
     return temp; 
    } 
} 

private void BindList(NameValueCollection nvpList) 
{ 
    resultGV.DataSource = nvpList.ToDictionary(); 
    resultGV.DataBind(); 
} 
+0

No puedo cambiarlo a Diccionario como su objeto ext y sigo usando Net 2.0. Pero gracias de cualquier manera. Cada opinión ayuda. –

+0

Tenga en cuenta que NameValueCollection puede tener claves duplicadas, mientras que Dictionary no. Por lo tanto, podría encontrarse con problemas/perder información al convertir a un diccionario. – magnattic

2

Finalmente utilicé la solución sugerida en la implementación de su extensión, pero sin extensión.

private void BindList(NvpList nvpList) 
    { 
    IDictionary dict = new Dictionary<string, string>(); 

    foreach (String s in nvpList.AllKeys) 
     dict.Add(s, nvpList[s]); 

    resultGV.DataSource = dict; 
    resultGV.DataBind(); 
    } 

tal vez haga alguna clase de ayuda que sea estática y haga la traducción en un solo lugar en lugar de muchas. Esta extensión es bastante útil ... :-)

Gracias. X.

6

Es un poco complicado, porque el enumerator devuelve solo las teclas. Sin embargo, se puede obtener el valor de clave con Container.DataItem, y luego mirar hacia arriba en el NameValueCollection para obtener el valor:

<asp:GridView id="gv" runat="server" AutoGenerateColumns="false"> 
    <Columns> 
     <asp:TemplateField HeaderText="Key"> 
     <ItemTemplate><%# Container.DataItem %></ItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="Value"> 
     <ItemTemplate> 
      <%# ((NameValueCollection)gv.DataSource)[(string)Container.DataItem] %> 
     </ItemTemplate> 
     </asp:TemplateField> 
    </Columns> 
</asp:GridView> 
+0

Consulte mi respuesta para un cambio necesario si está utilizando un control similar al del repetidor DataBound anidado con NameValueCollection –

1

Si usted tiene un anidado Repeater (o GridView también, estoy seguro), se necesita alterar Mark Brackett's answer para que se vea así, de lo contrario obtendrá un error en tiempo de ejecución acerca de no poder encontrar un control con el nombre rpt.

<asp:Repeater ID="rpt" runat="server"> 
<ItemTemplate> 
    <li> 
     <%# Container.DataItem %>: 
     <%# ((NameValueCollection)((Repeater)Container.Parent).DataSource)[(string)Container.DataItem] %> 
    </li>  
</ItemTemplate> 
</asp:Repeater> 
1

me parece que lo mejor es utilizar un StringDictionary de enlace de datos & acceder clave & valor

Dim sDict as New StringDictionary 
sDict.Add("1","data1") 
sDict.Add("2","data2") 
sDict.Add("3","data3") 
... 

CheckBoxList1.DataSource = sDict 
CheckBoxList1.DataValueField = "key" 
CheckBoxList1.DataTextField = "value" 
CheckBoxList1.DataBind() 
0

que tenía un problema similar que implica la unión de un diccionario (SortedDictionary en realidad) a un GridView y con ganas de cambiar el nombre del columnas Lo que terminó trabajando para mí es algo un poco más fácil de leer.

<asp:GridView ID="gv" runat="server" AutoGenerateColumns="False"> 
    <Columns> 
    <asp:TemplateField HeaderText="Attribute"> 
     <ItemTemplate> 
     <%# ((KeyValuePair<string,string>)Container.DataItem).Key %> 
     </ItemTemplate> 
    </asp:TemplateField> 
    <asp:TemplateField HeaderText="Value"> 
     <ItemTemplate> 
     <%# ((KeyValuePair<string,string>)Container.DataItem).Value %> 
     </ItemTemplate> 
    </asp:TemplateField> 
    </Columns> 
</asp:GridView> 

Esto funciona mediante la adopción de la Container.DataItem, el elemento actual del GridView está tratando de mostrar, coaccionar en su tipo real de datos (KeyValuePair) y luego mostrar la propiedad deseada de ese elemento.

Cuestiones relacionadas