Bind NameValueCollection to GridView?
Asked Answered
S

6

9

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.

Soundless answered 20/10, 2008 at 2:13 Comment(0)
B
8

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();
}
Biographical answered 20/10, 2008 at 2:21 Comment(2)
I can't change it to Dictionary as it's ext object and I am still using Net 2.0. But thanks...anyway. Every opinion helps.Soundless
Keep in mind though that NameValueCollection can have duplicate keys, while Dictionary does not. So you could run into trouble/lose information when converting to a Dictionary.Toxemia
H
6

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>
Hernadez answered 21/10, 2008 at 13:5 Comment(1)
See my answer for a necessary change if you are using a nested DataBound Repeater-like control with NameValueCollectionPhyl
S
2

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.

Soundless answered 21/10, 2008 at 12:41 Comment(0)
P
1

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>
Phyl answered 30/3, 2010 at 21:10 Comment(0)
R
1

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()
Risibility answered 13/8, 2011 at 10:56 Comment(0)
W
0

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.

Weinberg answered 29/3, 2012 at 17:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.