Bind NameValueCollection to GridView?

2019-04-06 13:34发布

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.

6条回答
神经病院院长
2楼-- · 2019-04-06 13:44

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()
查看更多
小情绪 Triste *
3楼-- · 2019-04-06 13:45

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>
查看更多
爷、活的狠高调
4楼-- · 2019-04-06 13:57

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>
查看更多
一夜七次
5楼-- · 2019-04-06 14:00

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.

查看更多
Juvenile、少年°
6楼-- · 2019-04-06 14:02

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();
}
查看更多
来,给爷笑一个
7楼-- · 2019-04-06 14:05

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.

查看更多
登录 后发表回答