What kind of collection I should use to convert NameValue collection to be bindable to GridView?
When doing directly it didn't work.
Code in aspx.cs
private void BindList(NameValueCollection nvpList)
{
resultGV.DataSource = list;
resultGV.DataBind();
}
Code in 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>
Any tip most welcome. Thanks. X.
Can you use Dictionary<string,string> instead of NameValueCollection. Since Dictionary<T,T> implements IEnumerable you could use LINQ as so:
resultGV.DataSource = from item in nvpDictionary
select new { Key = item.Key, Value = item.Value };
resultGV.DataBind();
[EDIT] Actually you may be able to use Dictionary directly as:
resultGV.DataSource = nvpDictionary;
resultGV.DataBind();
If it doesn't map key/value the way you want you can always go back to LINQ. LINQ would also allow you to rename the fields to whatever you want.
[EDIT] If you can't change to use Dictionary<T,T>, make a copy of the NameValueCollection as a Dictionary in the method and bind to it.
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();
}
If you do this a lot, you could write an extension method to convert to a Dictionary, and use it so.
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();
}
It's a little tricky, because the enumerator returns only the Keys. But, you can get the Key value with Container.DataItem, and then look up into the NameValueCollection to get the value:
<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>
Finally I used solution suggested in your extension implementation, but without extension itself.
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();
}
maybe do some helper class that will be static and do the translation for me in one place instead of many. This extension is quite handy... :-)
Thanks. X.
If you have a nested Repeater
(or GridView
too, I'm sure), you need to alter Mark Brackett's answer to look like this, or else you'll get a run-time error about not being able to find a control with the name of rpt.
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<li>
<%# Container.DataItem %>:
<%# ((NameValueCollection)((Repeater)Container.Parent).DataSource)[(string)Container.DataItem] %>
</li>
</ItemTemplate>
</asp:Repeater>
I find it best to use a StringDictionary for databinding & accessing key & value
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()
I had a similar problem involving binding a Dictionary (SortedDictionary really) to a GridView and wanting to rename the columns. What ended up working for me is some thing a little easier to read.
<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>
This works by taking the Container.DataItem, the current item the GridView is trying to display, coercing it into it's actual data type (KeyValuePair) and then displaying the desired property of that item.