在ListView asp.net中检索所选单选按钮的值

时间:2014-09-10 14:39:46

标签: asp.net

我想发送一个Guid,当用户点击结帐时,该Guid应与每个单选按钮关联为eventargs。我只用一个RadioButtonList就可以实现这个功能,但我不能在这里使用它,因为其余的字段是从数据库中提取的。

有很多问题涉及这类主题,但我找不到一个能够解决我想要实现的问题的问题。

我有以下列表

<asp:Content ID="SubscriptionContent" ContentPlaceHolderID="MainContent" ViewStateMode="Enabled" runat="server">
    <asp:Panel ID="SubscriptionPanel" CssClass="shopping-cart" ViewStateMode="Enabled" runat="server">
        <asp:ListView ID="NewSubscription" runat="server">
            <LayoutTemplate>
                <table class="table">
                    <thead>
                        <th>Select a Subscription</th>
                        <th>Subscription Level
                        </th>
                        <th>Description
                        </th>
                        <th>Price
                        </th>
                    </thead>
                    <tbody>
                        <tr id="itemPlaceholder" runat="server" />
                    </tbody>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr>
                    <td class="description"><asp:RadioButton ID="SubscriptionLevel" GroupName="SubscriptionRadio" Text='<%# Eval("SubscriptionLevel") %>' runat="server" /></td>
                    <td class="description"><asp:Label ID="Details" Text='<%# Eval("Details") %>' runat="server"></asp:Label></td>
                    <td class="price"><asp:Label runat="server" Text='<%# Eval("Price", "{0:C2}") %>'></asp:Label></td>
                    <asp:TextBox ID="Id" runat="server" Visible="false" Text='<%# Eval("Id") %>' />
                </tr>
            </ItemTemplate>
        </asp:ListView>

        <asp:Button ID="Subscribe" CssClass="btn btn-primary" runat="server" Text="<%$ Snippet: Ecommerce/ShoppingCart/CheckoutButtonLabel, Checkout %>" OnClick="BuySubscription" />
        <script type="text/javascript">
            $(document).ready(function () {
                $("input:radio").attr('name', 'SubscriptionRadio');//Override the naming that asp does                   
            });
        </script>
    </asp:Panel>
</asp:Content>

我想如果我可以使用每个单选按钮的相应guid值更新隐藏字段,并在用户触发BuySubscription时提交。我不知道该怎么做。最后,我只希望用户能够选择其中一个订阅选项并将该guid传递回函数。

提前感谢您的任何意见。

1 个答案:

答案 0 :(得分:2)

您遇到的第一个问题是,ASP.NET为每个<input type="radio" />提供了一个不同的名称,因为它位于不同的NamingContainer

您已添加了一些脚本以尝试通过更改客户端上的name属性来解决此问题。不幸的是,这不会奏效。当您将表单发布回服务器时,ASP.NET仍将使用生成的名称查找值,该名称不存在。

快速而肮脏的解决方案是更新脚本,将值从隐藏的TextBox复制到radiobutton的value属性。然后,您必须使用Request.Form["SubscriptionRadio"]来检索所选选项的值:

<ItemTemplate>
    <tr>
        <td class="description">
            <asp:RadioButton ID="SubscriptionLevel" runat="server"
                GroupName="SubscriptionRadio" 
                Text='<%# Eval("SubscriptionLevel") %>' 
            />
            <%-- NB: Can't set Visible="False", otherwise it's not rendered: --%>
            <asp:TextBox ID="Id" runat="server" 
                Style="display:none;"
                Text='<%# Eval("Id") %>' 
            />
        </td>
        ...
    </tr>
</ItemTemplate>
...
<script>
$(document).ready(function() {
    $("input:radio").each(function(){
        var me = $(this);
        var id = me.closest("tr").find("input[name$=Id]").val();
        me.attr("value", id);
        me.attr('name', 'SubscriptionRadio');
    });
});
</script>

或者,您可以使用在数据绑定控件中工作的自定义RadioButton控件。我在2012年发布了一个简单的例子:https://stackoverflow.com/a/13271444/124386

using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SiteControls
{
    [ToolboxData("<{0}:ListRadioButton runat=\"server\" />")]
    public class ListRadioButton : RadioButton
    {
       private static readonly FieldInfo UniqueGroupNameField = FindUniqueGroupNameField();
       private string _uniqueGroupName;

       private static FieldInfo FindUniqueGroupNameField()
       {
          return typeof(RadioButton).GetField("_uniqueGroupName", 
             BindingFlags.NonPublic | BindingFlags.Instance);
       }

       public string Value
       {
           get { return Attributes["value"]; }
           set { Attributes["value"] = value; }
       }

       protected virtual string CreateUniqueGroupName()
       {
          string result = GroupName;
          if (string.IsNullOrEmpty(result))
          {
             result = ID;
          }
          if (string.IsNullOrEmpty(result))
          {
             result = UniqueID;
          }
          else
          {
             Control container = NamingContainer;
             if (container != null)
             {
                if (container is IDataItemContainer)
                {
                   container = container.NamingContainer ?? container;
                }

                result = container.UniqueID + base.IdSeparator + result;
             }
             else
             {
                string uniqueID = UniqueID;
                if (!string.IsNullOrEmpty(uniqueID))
                {
                   int index = uniqueID.LastIndexOf(base.IdSeparator);
                   if (index != -1)
                   {
                      result = uniqueID.Substring(0, 1 + index) + result;
                   }
                }
             }
          }

          return result;
       }

       private void EnsureUniqueGroupName()
       {
          if (_uniqueGroupName == null)
          {
             string value = CreateUniqueGroupName();
             if (UniqueGroupNameField != null) UniqueGroupNameField.SetValue(this, value);
             _uniqueGroupName = value;

             value = base.Attributes["value"];
             if (string.IsNullOrEmpty(value))
             {
                base.Attributes["value"] = UniqueID;
             }
          }
       }

       protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
       {
          EnsureUniqueGroupName();
          return base.LoadPostData(postDataKey, postCollection);
       }

       protected override void Render(HtmlTextWriter writer)
       {
          EnsureUniqueGroupName();
          base.Render(writer);
       }
    }
}

您可以在页面标记中注册控件:

<%@ Register tagPrefix="site" namespace="SiteControls" %>

或在web.config文件中:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <pages>
            <controls>
                <add 
                    tagPrefix="site" 
                    namespace="SiteControls"
                />
            </controls>
        </pages>
    </system.web>
</configuration>

有了这个,您可能会丢失脚本和隐藏的TextBox

<ItemTemplate>
    <tr>
        <td class="description"><site:ListRadioButton ID="SubscriptionLevel" runat="server"
            GroupName="SubscriptionRadio" 
            Text='<%# Eval("SubscriptionLevel") %>'
            Value='<%# Eval("Id") %>'
        /></td>
        ...

要查找所选项目,您需要循环浏览ListView Items,找到RadioButton控件,然后查看{{1} property:

Checked