【问题标题】:nested ListView not getting values from parent listview嵌套的 ListView 没有从父 listview 获取值
【发布时间】:2016-08-12 23:51:24
【问题描述】:

我的网站是 C# 并且是完全动态的。菜单栏也是动态的。每个导航菜单都有子菜单。因为需要从数据库构建菜单,所以我使用了 Listview 控件。在我的菜单网站中,我需要在一个父 Listview 中使用 2 个子 Listview。所以它看起来像这样。

父菜单列表视图有子菜单列表视图和子菜单列表视图有另一个子列表视图,我需要在其中显示任何一个产品相关的父列表视图类别..

我的子菜单已正确构建,但在其中如果我尝试绑定另一个 Listview,则会显示错误(对象引用未设置为对象的实例。)然后我尝试使用手动 sql 查询而没有从 where 子句中获取定义的 ItemDataBound 也显示相同的错误。

我的菜单看起来如何(子菜单中的空白区域(右侧)我想显示一种移动电源类别的产品)

<asp:ListView ID="mainMenu" runat="server" DataKeyNames="name" OnItemDataBound="OnItemDataBound">
     <ItemTemplate>
          <li><asp:HyperLink ID="mainLinks" runat="server" NavigateUrl='<%# Eval("name", "~/{0}") %>' Text='<%# Eval("name") %>'></asp:HyperLink>

              <ul class="super-child">
                  <asp:ListView ID="childMenu" runat="server" DataKeyNames="name">
                       <ItemTemplate>
                            <div class="super-child-inner">
                                 <div class="list-child">
                                 <li><asp:HyperLink ID="cat3" runat="server" NavigateUrl='<%# Eval("category") & Eval("name", "/{0}") %>' Text='<%# Eval("name") %>'></asp:HyperLink></li>
                            </div>

                            <div class="recommended">
                            <asp:ListView ID="recommendedProducts" runat="server">
                                 <ItemTemplate>
                                     <div class="rec-img">
                                          <asp:Image ID="recImg" runat="server" ImageUrl='<%# Eval("image") %>' />
                                     </div>
                                     <p class="rec-name"><asp:HyperLink ID="recLink" runat="server" NavigateUrl='<%# Eval("category") & Eval("name", "/{0}") %>' Text='<%# Eval("name") %>'></asp:HyperLink></p>
                                 </ItemTemplate>
                              </asp:ListView>
                          </div>
                      </div>
                  </ItemTemplate>
              </asp:ListView>
           </ul>
        </li>
    </ItemTemplate>
</asp:ListView>

ItemData绑定代码

protected void onItemDataBound(object sender, ListViewItemEventArgs e)
{
    if (e.Item.ItemType == ListViewItemType.DataItem) {
        ListViewDataItem itm = (ListViewDataItem)e.Item;
        string name = mainMenu.DataKeys(itm.DataItemIndex)("name");
        ListView childMenu = e.Item.FindControl("childMenu") as ListView;
        ListView recommendedProducts = e.Item.FindControl("recommendedProducts") as ListView;
        string constr = ConfigurationManager.ConnectionStrings("conio").ConnectionString;
        using (MySqlConnection con = new MySqlConnection(constr)) {
            using (MySqlCommand cmd = new MySqlCommand()) {
                cmd.CommandText = "SELECT * FROM product_categories WHERE category = '" + name + "' and status = 'active'";
                cmd.Connection = con;
                using (MySqlDataAdapter sda = new MySqlDataAdapter(cmd)) {
                    DataTable dt = new DataTable();
                    sda.Fill(dt);
                    childMenu.DataSource = dt;
                    childMenu.DataBind();
                }
            }
        }

        try {
            string constr2 = ConfigurationManager.ConnectionStrings("conio").ConnectionString;
            using (MySqlConnection con = new MySqlConnection(constr2)) {
                using (MySqlCommand cmd = new MySqlCommand()) {
                    cmd.CommandText = "SELECT ID,slug,product_name,image FROM products WHERE (category Like @category) and status = 'active' Limit 1";
                    cmd.Connection = con;
                    cmd.Parameters.AddWithValue("@categoty", "%" + name + "%");
                    using (MySqlDataAdapter sda = new MySqlDataAdapter(cmd)) {
                        DataTable dt = new DataTable();
                        sda.Fill(dt);
                        recommendedProducts.DataSource = dt;
                        recommendedProducts.DataBind();
                    }
                }
            }
        } catch (Exception ex) {
            Response.Write(ex);
        }
    }
}

更新(例外)

System.NullReferenceException:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79System.NullReferenceException 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处:对象引用未设置为对象的实例。在 E:\MY WEB\brandstik.com1\MasterPage.master.vb:line 79 中的 MasterPage.onItemDataBound(Object sender, ListViewItemEventArgs e) 处

【问题讨论】:

  • 我认为名称有问题 - 在您的 DOM 中 ListView ID 是 = recommendedProduct 但您正在尝试将数据绑定到 ListView recommendedProducts 所以先检查一下。
  • @codelahiru 是的,你是对的,我在那里犯了错误,但我用正确的名称更改了它,但问题仍然存在
  • 除了Object reference not set as an instance of an object.之外还有什么例外吗?这意味着在将数据绑定到该实例之前,您没有从该实例创建任何新对象。
  • @codelahiru 我在我的帖子中发布了整个异常。请看看..
  • @codelahiru 你发现我的代码有什么错误吗?

标签: c# asp.net listview


【解决方案1】:

为了解决这个问题,需要理解两个主要概念。

  • ID 值的范围
  • 初始化时间

关于ID值的范围:

ItemTemplate 中的元素 ID 将仅在此项范围内可用。否则,多个项目会产生具有重复 ID 值的元素。 childMenu 中有两项,您希望FindControl 返回哪一项?

关于时间,ListView 的嵌套项只会在DataSource 被赋值之后DataBind 被执行后才会被创建。这意味着,您不能期望 recommendedProductschildMenu.DataSource = dt; childMenu.DataBind(); 被执行之前存在。

在以下示例中,您复杂的数据逻辑被简单但有效的调试值所取代:

protected void Page_Load(object sender, EventArgs e)
{
    mainMenu.DataSource = new[] { "M1", "M2" };
    mainMenu.DataBind();
}

protected void mainMenu_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    var childMenu = e.Item.FindControl("childMenu") as ListView;

    // will always be null, because ID scope is not correct
    ListView recommendedProducts1 = e.Item.FindControl("recommendedProducts") as ListView;

    // query the correct ID scope, but Items will be empty
    foreach (var item in childMenu.Items)
    {
        var recommendedProducts2 = item.FindControl("recommendedProducts") as ListView;
    }

    // initialize sub-items
    childMenu.DataSource = new object[] { "C1", "C2" };
    childMenu.DataBind();

    // query the correct ID scope, with items
    foreach (var item in childMenu.Items)
    {
        // finally, recommendedProducts for each childmenu-item within the currently processed childmenu is accessible
        var recommendedProducts3 = item.FindControl("recommendedProducts") as ListView;
        recommendedProducts3.DataSource = new[] { "Best" };
        recommendedProducts3.DataBind();
    }
}

为了完整起见,我测试了 ASPX:

<asp:ListView ID="mainMenu" runat="server" OnItemDataBound="mainMenu_ItemDataBound">
    <LayoutTemplate>
        <ul>
            <li id="itemPlaceholder" runat="server"/>
        </ul>
    </LayoutTemplate>
    <ItemTemplate>
        <li runat="server">
            <%# Container.DataItem %>
            <asp:ListView ID="childMenu" runat="server">
                <LayoutTemplate>
                    <ul>
                        <li id="itemPlaceholder" runat="server"/>
                    </ul>
                </LayoutTemplate>
                <ItemTemplate>
                    <li runat="server">
                        <%# Container.DataItem %>
                        <div class="recommended">
                            <asp:ListView ID="recommendedProducts" runat="server">
                                <ItemTemplate>
                                    <div style="background-color:green">
                                        <%# Container.DataItem %>
                                    </div>
                                </ItemTemplate>
                            </asp:ListView>
                        </div>
                    </li>
                </ItemTemplate>
            </asp:ListView>
        </li>
    </ItemTemplate>
</asp:ListView>

希望这有助于您了解、何时以及如何访问您的控件。

【讨论】:

  • @SUN 现在我很好奇...这是您的代码问题还是问题的问题?如果是代码问题:您在 cmets 中说您已经调试了代码 - 很明显 recommendedProducts 为空。现在怎么样了?
  • 在我的更新中,从代码更改 ListView 名称后出现完全相同的错误,但我不明白为什么错误仍然保持不变..
  • 也可能是初始化的问题,因为recommendedProductschildMenu的子项,而childMenu在代码执行时为空(你在方法中填写,在你查询@987654333之后@)。尝试查询ListView recommendedProducts = childMenu.FindControl("recommendedProducts") as ListView AFTER childMenu is initialized with datasource
  • @SUN 已编辑,现在应该足以解决问题了。
  • 虽然这种技术可能很好,但我们也可以在不包含第三个子列表视图的情况下做到这一点并且可以在第二个子列表视图中包含第三个子内容并绑定第二个列表视图,如果我们可以构造 mysql 查询以连接两者表格,即产品和类别
猜你喜欢
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2015-04-04
  • 2021-11-06
  • 2011-02-02
  • 1970-01-01
  • 2021-05-19
  • 2018-07-05
相关资源
最近更新 更多