在转发器中生成ListItem

时间:2013-05-20 21:09:39

标签: asp.net data-binding repeater

我有一个ASP.NET转发器正在加载衬衫供购买。数据存储在XML文件中,我有可用的衬衫大小,逗号分隔格式,所以一件衬衫是S,M,L,另一件是S,M,L,XL。

由于我使用转发器,我试图执行以下操作:

<asp:DropDownList ID="ddlSize" runat="server">
  <asp:ListItem Text="Choose" />
</asp:DropDownList>

<% For Each s As String In XPath("Sizes").Split(",")
  Me.ddlSize.Items.Add(New ListItem(s, s))
Next %>

我收到ddlSize不是页面成员的错误,所以我假设下拉列表不在范围内?无论如何,在转发器中生成列表项的最佳方法是什么?谢谢!

编辑1 - 根据评论,我的XML结构如下:

<product>
    <name>Golf Shirt</name>
    <description>Nike branded</description>
    <cost>49.99</cost>
    <sizes>S,M,L,XL</sizes>
</product>

2 个答案:

答案 0 :(得分:0)

以下是您需要做的事情。将此添加到您的代码后面。假设您正在使用c#,但如果没有,您可以轻松地转换它(只需谷歌c#到vb)。我不会在页面中执行此操作,而是在代码后面执行此操作。此外,您的示例x​​ml没有任何类型的密钥,除非您使用btw是个坏主意的“名称”节点。我建议您考虑将xml更改为以下内容:

 <?xml version="1.0" encoding="utf-8" ?>
<products>
<product id="1">
  <name>Golf Shirt</name>
  <description>Nike branded</description>
  <cost>49.99</cost>
  <sizes>S,M,L,XL</sizes>
 </product>
 <product id="2">
  <name>Another Golf Shirt</name>
  <description>Ashworth branded</description>
  <cost>59.99</cost>
  <sizes>S,M,L,XL,XXL</sizes>
 </product>
</products>

下面的内容是加载控件时它会抓取xml doc然后使用你的密钥(很可能你会在产品页面上它会有一些密钥,如果没有使用“name”节点但是又一次小心)选择单个节点。我们采用尺寸和修剪/替换来确保我们没有额外的空间等等。然后将每个字符串数组中的每一个添加到下拉列表中。

  protected void ddlSize_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            // get reference to dropdown
            var ddl = (DropDownList)sender;

            // clear existing items if not it will keep appending.
            ddl.Items.Clear();

            // add default choose item.
            ddl.Items.Add(new ListItem("Choose", ""));

            // get the xml document.
            var xDoc = new XmlDocument();
            var path = Server.MapPath("~/items.xml");
            xDoc.Load(path);

            // you'll want to get this id from a param from your page or something.
            // this is because I'm assuming you'll have several products you'll need to grab
            // the product but the "name" node or an attribute as I've added called "id" or something.
            var id = 1;

            // select the sizes node based on our id as described above.
            var node = xDoc.SelectSingleNode("//product[@id='" + id + "']//sizes");

            // split to string array but trim and replace any spaces just in case.
            string[] sizes = node.InnerText.ToString().Trim().Replace(" ", "").Split(',');

            // iterate sizes and add them to the drop down.
            foreach (string s in sizes)
            {
                ddl.Items.Add(new ListItem(s, s));
            }
        }            

    }
这可能看起来很多但不是真的。您可以调查一些辅助方法/扩展,这些方法/扩展将放在一个帮助程序类中,这将清理您需要的每个下拉列表等。您还可以根据xml doc缓存的大小等,但这是另一个主题。

答案 1 :(得分:0)

建议的答案很有帮助,但最终对我的方案没有用,因为它需要重新读取数据源,然后找到一种方法来跟踪我当前正在尝试加载的“哪个产品”。

最后,我能够将ListDataBound事件用于我的listview,找到我的dropdownlist控件,并使用DataBinder.Eval函数来解析我的数据并添加项目。代码示例如下,适用于任何好奇的人。

If e.Item.FindControl("ddlSize") IsNot Nothing Then
    'Get our dropdownlist
    Dim ddl As DropDownList = CType(e.Item.FindControl("ddlSize"), DropDownList)
        'Make sure we didn't already add items to this ctrl
        If ddl.Items.Count = 0 Then
            'get our sizes, which are stored in comma delimited format
            Dim sizes() As String = DataBinder.Eval(e.Item.DataItem, "Sizes").ToString.Split(",")
            'add our items
            For Each s As String In sizes
                ddl.Items.Add(New ListItem(s, s))
            Next
        End If
    End If
相关问题