【问题标题】:Retrieve value for selected radiobutton in ListView asp.net检索 ListView asp.net 中选定单选按钮的值
【发布时间】:2014-09-20 01:14:38
【问题描述】:

当用户单击结帐时,我想发送一个应该与每个单选按钮关联的 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 传递回函数。

提前感谢您的任何意见。

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    您将遇到的第一个问题是 ASP.NET 为每个 &lt;input type="radio" /&gt; 赋予不同的名称,因为它位于不同的 NamingContainer 中。

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

    快速而肮脏的解决方案是更新您的脚本,将隐藏的TextBox 中的值复制到单选按钮的值属性中。然后您必须使用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>
            ...
    

    要找到选定的项目,您需要遍历ListViewItems,找到RadioButton 控件,然后查看Checked 属性:

    ListRadioButton selectedItem = NewSubscription.Items
        .Select(item => (ListRadioButton)item.FindControl("SubscriptionLevel"))
        .FirstOrDefault(radio => radio != null && radio.Checked);
    
    string selectedValue = (selectedItem == null) ? null : selectedItem.Value;
    

    【讨论】:

    • 上述扩展为单选按钮的代码是否会放在我的 CodeBehind 文件中?我是 cannot resolve tag 站点和 ListRadioButton 的例外,我对直接 ASP.NET 有点陌生,主要使用带有 Razor 的 MVC5。如果这是一个愚蠢的问题,请提前道歉。
    • @ZachM.:ListRadioButton 将放在单独的类文件中。如果您使用的是网站项目,可以将其添加到App_Code 文件夹;对于 Web 应用程序项目,只需将其添加为类即可。然后,您需要在页面标记或web.config 文件中注册控件。
    • 这就像一个魅力,你先生是 ASP.NET 世界的圣人。
    • 你错过了这段代码$(document.ready(...的右括号
    • @ChrisNash:谢谢 - 现在应该修复了。
    猜你喜欢
    • 1970-01-01
    • 2017-01-27
    • 2023-04-03
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多