首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ASP.NET中的List <T>和ListViews的Dictionary <T>问题怎么解决?

ASP.NET中的List <T>和ListViews的Dictionary <T>问题怎么解决?
EN

Stack Overflow用户
提问于 2018-02-20 03:38:15
回答 2查看 0关注 0票数 0

序言

我问这个问题,因为即使我已经读了很多ListView资源,我仍然没有“得到”它。

背景

我有一堆Foo有一个与它们相关的项目列表(称为Bar),并且将它们从数据访问/业务逻辑层作为包含Foo及其关联的bar的Dictionary拖动。 我想连接在网页上的这些项目到一个ListView,左侧保存Foo.Name,并在下拉列表中右侧的List <Bar>。 (下面用ASCII展示):

ListView

代码语言:javascript
复制
------------------------------------------------------------------
|           Name Of Item          |  DropDownList (of List<T>)   |
|---------------------------------|  _____________________       |
|                foo1             |  |     bar1      | v |       |
|                                 |  |_______________|___|       |  
------------------------------------------------------------------
|                                 |  DropDownList (of List<T>)   |
|                                 |  _____________________       |
|                foo2             |  |     bar2      | v |       |
|                                 |  |_______________|___|       |
------------------------------------------------------------------

这是一个ListView; 这些项目从一个数据库被拉到Dictionary <Foo,List <Bar>。 我试图让dictionary中的键值显示在“项目名称”下,并试图让List <T> Bar显示为ListView右侧的DropDownList。

类图

代码语言:javascript
复制
-----------------          -----------------
|   Foo         |          |  Bar          |
-----------------          -----------------
|  Id           |          |  ItemName     |
|  Name         |          |  ItemValue    |
|  BarID        |          |               |
-----------------          -----------------

所以要回顾一下,我想将Dictionary.Key“Name”放置在ListView的左侧,而Dictionary.Value(恰好是一个列表)放到右侧的DropdownList中。

因此,对于每个键/值对,都会有一个名称和一个下拉列表来存放每个键的值。

但是我遇到了问题,希望有人能告诉我我做错了什么。

代码:

代码语言:javascript
复制
  protected Dictionary<Foo, List<Bar>> FooDictionary
        {
            get; 
            set; 
        }

protected void DataBindFooList(List<int> SelectedFoos)
        {
            System.Web.UI.WebControls.ListView lv = lvFooList;

try
            {
                Dictionary<Foo, List<Bar>> fooDictionary =
                    new Dictionary<Foo, List<Bar>>();

                foreach (int Foo in SelectedFoos)
                {
                 // Build List of Foos to add as Dictionary.Keys
                 fooDictionary.Add(fooScalar, Bar)                     
                }
                FooDictionary = fooDictionary;
                lv.DataSource = FooDictionary;
                lv.DataBind();
                ddlListOfBars.DataSource = FooDictionary;
                ddlListOfBars.DataValueField = "ItemValue";
                ddlListOfBars.DataTextField = "ItemName";
                ddlListOfBars.DataBind();
            }
            catch (Exception ex)
            {
                SetMessage(divFooMsg, "Unable to retrieve Foos: " + 
                ex.Message, true, true);
            }

ListView代码:

代码语言:javascript
复制
<asp:ListView ID="lvFooList" runat="server">
   <LayoutTemplate>
      <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
   </LayoutTemplate>
      <ItemSeparatorTemplate>
         <hr />
      </ItemSeparatorTemplate>
   <ItemTemplate>
      <%#Eval("Name") %>
      <asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>
    </ItemTemplate>
   </asp:ListView>

问题:

  1. 用这种方式使用字典可以吗?
  2. 我哪里出问题了有什么建议吗?(资源、提示等)
  3. 有更好的方法吗?
  4. 如果这个问题很清楚,请评论,以便我能弄清楚如何改进它。
EN

回答 2

Stack Overflow用户

发布于 2018-02-20 12:13:47

你的问题出现了,因为在DataBindFooList()中绑定ddlListOfBars没有意义,因为不只有一个DropDownList可以绑定到数据绑定。 当你调用lv.DataBind()时,ListView会为每个Foo创建一个ItemTemplate的副本,每个副本都包含一个ddlListOfBars。 您需要告诉它将每个DropDownList绑定到正确的List <Bar>。 你可以通过设置ddlListOfBars的数据源,而不是在后面的代码中做到这一点:

代码语言:javascript
复制
<ItemTemplate>
  <%#Eval("Key.Name") %>
  <asp:DropDownList
        ID="ddlListOfBars"
        runat="server"
        DataSource='<%#Eval("Value")%>'
        DataValueField="ItemValue"
        DataTextField="ItemName" />
</ItemTemplate>

请注意,还需要使用“Key.Name”来获取Foo的name属性。 要绑定的单个字典项是KeyValuePair <Foo,List <Bar>,它具有分别访问Foo和List <Bar>的Key属性和Value属性。

如果你在ItemTemplate中有很多东西,那么将内容移出到用户控件中会很有用。 用户控件可以有一个强类型的属性来访问DataItem,并且具有对其子控件的强类型访问。 这样就可以在没有所有Cast和FindControl()噪声的情况下获得ItemDataBound事件的灵活性。 我怀疑在这种情况下我会打扰,但它会像这样

代码语言:javascript
复制
<asp:ListView ID="lvFooList" runat="server">
<LayoutTemplate>
  <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
  <ItemSeparatorTemplate>
     <hr />
  </ItemSeparatorTemplate>
<ItemTemplate>
  <uc:ListViewContents DataItem='<%# Container.DataItem %>' />
</ItemTemplate>

ListViewContents.ascx..

代码语言:javascript
复制
<asp:Label ID="lbName" runat="server"/>
<asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>

ListViewContents.ascx.cs..。

代码语言:javascript
复制
public KeyValuePair<Foo,List<Bar>> DataItem
{
    get; set;
}

protected override void OnDataBinding(EventArgs e)
{
    base.OnDataBinding(e);

    lbName.Text = DataItem.Key.Name;

    ddlListOfBars.DataTextField = "ItemName";
    ddlListOfBars.DataValueField = "ItemValue";
    ddlListOfBars.DataSource = DataItem.Value;
    ddlListOfBars.DataBind();   
}
票数 0
EN

Stack Overflow用户

发布于 2018-02-20 13:07:22

就像你想要的那样:

代码语言:javascript
复制
   <asp:ListView ID="lvFooList" runat="server">
    <LayoutTemplate>
      <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
    </LayoutTemplate>
      <ItemSeparatorTemplate>
         <hr />
      </ItemSeparatorTemplate>
    <ItemTemplate>
      <asp:Label ID="lbName" runat="server"/>
      <asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>
    </ItemTemplate>
   </asp:ListView>

然后我写了一个非常快速的测试

代码语言:javascript
复制
    public class Foo
    {
        public string Name;
    }

    public class Bar
    {
        public string ItemName { get; set; }
        public string ItemValue { get; set; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

        var fooKey1 = new Foo() {Name = "foo1"};
        var barList1 = new List<Bar>()
               {
                   new Bar() {ItemName = "bar1", ItemValue = "barV1"},
                   new Bar() {ItemName = "bar2", ItemValue = "barV2"}
               };
        var fooKey2 = new Foo() {Name = "foo2"};
        var barList2 = new List<Bar>()
               {
                   new Bar() {ItemName = "bar3", ItemValue = "barV3"},
                   new Bar() {ItemName = "bar4", ItemValue = "barV4"}
               };

        var dicFooBar = new Dictionary<Foo, List<Bar>>() {{fooKey1, barList1}, {fooKey2, barList2}};

        lvFooList.ItemDataBound += lvFooList_ItemDataBound;
        lvFooList.DataSource = dicFooBar;
        lvFooList.DataBind();
    }

    void lvFooList_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        var dataItem = (ListViewDataItem)e.Item;
        var fooBarList = (KeyValuePair<Foo, List<Bar>>)dataItem.DataItem;

        ((Label) dataItem.FindControl("lbName")).Text = fooBarList.Key.Name;

        var ddlListOfBars = (DropDownList) dataItem.FindControl("ddlListOfBars");
        ddlListOfBars.DataTextField = "ItemName";
        ddlListOfBars.DataValueField = "ItemValue";
        ddlListOfBars.DataSource = fooBarList.Value;
        ddlListOfBars.DataBind();
    }

似乎做你想做的,但我的代码只是快速测试代码,所以请注意。不过,它确实呈现出了预期的效果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100007400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档