ASP.NET RadioButton возится с именем (groupname)

Я получил шаблонный элемент управления (ретранслятор), в котором перечислены некоторые текстовые и другие разметки. У каждого элемента есть связанная с ним радиомаяка, позволяющая пользователю выбирать ОДИН из элементов, созданных ретранслятором.

Повторитель записывает радиокассету, устанавливая свой идентификатор и имя, сгенерированные стандартным соглашением об именах по умолчанию для ASP.NET, которое делает каждую радиообъектуру полной "группой". Это означает, что все радиообъекты независимы друг от друга, что, к сожалению, означает, что я могу одновременно выбрать все радиообъективы. У радиообъектива есть умный атрибут "имя группы", используемый для установки общего имени, поэтому они группируются вместе и, следовательно, должны зависеть (поэтому я могу выбирать только по одному). Проблема в том, что это не работает - ретранслятор гарантирует, что идентификатор и, следовательно, имя (которое контролирует группировку) отличаются.

Поскольку я использую ретранслятор (возможно, это список или любой другой шаблонный контроль привязки данных), я не могу использовать RadioButtonList. Так где же это оставляет меня?

Я знаю, что раньше у меня была эта проблема, и решил. Я знаю, что почти у каждого программиста ASP.NET, должно быть, тоже было это, поэтому почему я не могу найти Google и найти надежное решение проблемы? Я наткнулся на решения для обеспечения группировки JavaScript (уродливые!) Или даже для обработки радиообъектов как не-серверных элементов управления, заставляя меня делать Request.Form[name] для чтения состояния. Я также попытался поэкспериментировать с переопределением атрибута name в событии PreRender - к сожалению, страница владельца и мастер-страница снова переопределяют это имя, чтобы отразить полное имя/имя, поэтому я получаю тот же неправильный результат.

Если у вас нет лучшего решения, чем то, что я опубликовал, вы по-прежнему очень рады опубликовать свои мысли - по крайней мере, я буду знать, что мой друг "Джек" прав о том, как иногда перепутался ASP.NET;)

Ответ 1

Google-fu: проблема ретранслятора asp.net radiobutton

Действительно, неудачное последствие искажения. Мой прием будет создавать или выбрать один из многих доступных настраиваемых элементов управления, который добавляет поддержку для этого имени на клиенте.

Ответ 2

Совет ASP.NET: использование элементов управления RadioButton в ретрансляторе

Это код для функции JavaScript:

function SetUniqueRadioButton(nameregex, current)
{
   re = new RegExp(nameregex);
   for(i = 0; i < document.forms[0].elements.length; i++)
   {
      elm = document.forms[0].elements[i]
      if (elm.type == 'radio')
      {
         if (re.test(elm.name))
         {
            elm.checked = false;
         }
      }
   }
   current.checked = true;
}

Код связан с ретранслятором через событие ItemDataBound. Чтобы он работал правильно, вам нужно знать имя элемента Repeater, а также имя GroupName, которое вы назначаете RadioButtons. В этом случае я использую rptPortfolios как имя Repeater и Portfolios в качестве имени группы:

protected void rptPortfolios_ItemDataBound(object sender,
                                           RepeaterItemEventArgs e)
{
   if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType
      != ListItemType.AlternatingItem)
      return;

   RadioButton rdo = (RadioButton)e.Item.FindControl("rdoSelected");
   string script =
      "SetUniqueRadioButton('rptPortfolios.*Portfolios',this)";
   rdo.Attributes.Add("onclick", script);

}

REF: http://www.codeguru.com/csharp/csharp/cs_controls/custom/article.php/c12371/

Ответ 3

Я использую jQuery script:

<script type="text/javascript">
    function norm_radio_name() {
        $("[type=radio]").each(function (i) {
            var name = $(this).attr("name");
            var splitted = name.split("$");
            $(this).attr("name", splitted[splitted.length - 1]);
        });
    };

    $(document).ready(function () {
        norm_radio_name();
    });

    // for UpdatePannel
    var prm = Sys.WebForms.PageRequestManager.getInstance();

    prm.add_endRequest(function () {
        norm_radio_name();
    });
</script>

Ответ 4

Я знаю, что это старый пост, но вот что я сделал с списком. Мой список просматривается в коде VB, поэтому я не уверен, что это будет хорошо работать с ретранслятором, но я думаю, что это может быть похоже.

То, что я делал, это обработать событие OnCheckChanged радиокнопками с функцией, которая не выбрала никаких других переключателей. Затем я искал выбранный переключатель, когда я переходил от страницы.

Это решение избегает JavaScript и jQuery и полностью игнорирует проблему GroupName. Он не идеален, но он функционирует как ожидаемый (I). Я надеюсь, что это будет полезно для других.

Разметка:

<asp:ListView ID="lvw" runat="server">
  <LayoutTemplate>`
    <table>
      <th>Radio</th>
      <tr id="itemPlaceholder"></tr>
    </table>
  </LayoutTemplate>
  <ItemTemplate>
    <tr>
      <td><asp:RadioButton ID="rdbSelect" runat="server" AutoPostBack="true"
           OnCheckedChanged="rdbSelect_Changed"/></td>
    </tr>
  </ItemTemplate>
</asp:ListView>

код:

Protected Sub rdbSelect_Changed(ByVal sender As Object, ByVal e As System.EventArgs)

  Dim rb1 As RadioButton = CType(sender, RadioButton)

  For Each row As ListViewItem In lvw.Items
    Dim rb As RadioButton = row.FindControl("rdbSelect")
      If rb IsNot Nothing AndAlso rb.Checked Then
         rb.Checked = False
      End If
  Next
  rb1.Checked = True
End Sub

И затем при нажатии кнопки "Отправить":

Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs)  Handles btnSubmit.Click

  For Each row As ListViewItem In lvw.Items
    Dim rb As RadioButton = row.FindControl("rdbSelect")
        Dim lbl As Label
        If rb IsNot Nothing AndAlso rb.Checked = True Then
            lbl = row.FindControl("StudentID")
            Session("StudentID") = lbl.Text
        End If
    Next

    Response.Redirect("~/TransferStudent.aspx")
End Sub

Ответ 5

Владимир Смирнов уже создал отличный пользовательский элемент управления, который решает эту проблему. Мы использовали GroupRadioButton в наших проектах, и он отлично работает с радио-кнопками, созданными внутри ретранслятора, а другие вне ретранслятора - все это часть той же группы.

Ответ 6

Это может быть немного лучше.

У меня есть usercontrol, который по существу представляет собой набор радиообъектов внутри ретранслятора, каждый экземпляр usercontrol имеет общедоступное свойство FilterTitle, которое уникально для каждого экземпляра.

добавьте эти два свойства в ваш радиоблок, заменив FilterTitle своим собственным именем публичной собственности

onclick='<%# "$(\"input[name$=btngroup_" + FilterTitle + "]\").removeAttr(\"checked\"); $(this).attr(\"checked\",\"checked\");" %>' GroupName='<%# "btngroup_" + FilterTitle  %>'

проще..

onclick="$('input[name$=btngroup1]').removeAttr('checked'); $(this).attr('checked','checked');" GroupName="btngroup1"

Ответ 7

Здесь чисто Javascript решение для полноты.

Просто добавьте этот атрибут onclick к элементу RadioButton (замените GroupName на RadioButton GroupName):

<asp:RadioButton ... GroupName="GroupName" onclick="SelectRadioButton('GroupName$',this)" ... />

И включите этот Javascript на свою страницу:

<script type="text/javascript">
function SelectRadioButton(regexPattern, selectedRadioButton)
    {
        regex = new RegExp(regexPattern);
        for (i = 0; i < document.forms[0].elements.length; i++)
        {
            element = document.forms[0].elements[i];
            if (element.type == 'radio' && regex.test(element.name))
            {
                element.checked = false;
            }
        }
        selectedRadioButton.checked = true;
    }
</script>

Ответ 8

Создайте пользовательский элемент управления и переопределите UniqueID в listview UniqueID + GroupName

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MYCONTROLS
{

[ToolboxData("<{0}:MYRADIOBUTTON runat=server></{0}:MYRADIOBUTTON >")]
public class MYRADIOBUTTON : RadioButton
{
    public override string UniqueID
    {
        get
        {
            string uid = base.UniqueID;
            //Fix groupname in lisview
            if (this.Parent is ListViewDataItem && GroupName != "")
            {
                uid = this.Parent.UniqueID;
                uid = uid.Remove(uid.LastIndexOf('$'));
                uid += "$" + GroupName;

            }
            return uid;


        }
    }

}
}

Его настраиваемый элемент управления, который наследуется от RadioButton (публичный класс MYRADIOBUTTON: RadioButton). Если вы ничего не делаете в классе, вы получаете нормальный RadioButton. Переопределяя UniqueId, вы можете изменить логику того, как визуализируется атрибут name. Чтобы сохранить имя уникальным для других элементов управления на странице (вне списка), вы можете получить UniqueId из ListView и добавить к нему имя GroupName и добавить его в RadioButton.

Это устранит проблему с группировкой RadioButtons в разных строках в списке. Возможно, вы захотите добавить еще одну логику с свойством включить/отключить эту функцию, чтобы она вела себя как обычный RadioButton.

Ответ 9

Я знаю, что этот вопрос немного устарел, но я думаю, что это может помочь кому-то, поэтому опубликовано мое решение этой проблемы.

Эта проблема состоит из двух частей:

  • Чтобы предотвратить выбор нескольких переключателей одновременно.
  • Чтобы узнать, какой переключатель был нажат на серверном коде.

У меня была аналогичная проблема с кнопкой Radio в Repeater. Я нашел частичное решение здесь: Простое исправление для элементов управления Radio Button в репитере ASP.NET с использованием jQuery

Прочтите эту статью, чтобы понять ее. Я передал эту статью, и это была хорошая помощь. Как упоминалось выше, эта проблема состоит из двух частей, прежде всего, для предотвращения выбора более чем одного переключателя за раз. Во-вторых, чтобы узнать, какой переключатель был нажат на серверном коде. Решение, опубликованное в этой статье, работало для меня только для первой части. Однако код, написанный там, а также обновления, размещенные там, не помогли мне. Поэтому мне пришлось немного изменить его, чтобы заставить его работать. Вот мое решение.

Я хотел создать опрос с помощью кнопки Vote. Имя моего переключателя (ID) - PollGroupValue с именем группы, установленным PollGroup в ретрансляторе. Помните, что атрибут Groupname в ASP.net отображается как атрибут имени в сгенерированном html. Мой код выглядит следующим образом:

<script type="text/javascript">

/*  Step-01: */
$(document).ready(function () {

    /*  Step-02: */
    $("[name*='PollGroup']").each(function () {
        $(this).attr('ci-name', $(this).attr('name'));
    });

    /*  Step-03: */
    $("[name*='PollGroup']").attr("name", $("[name*='PollGroup']").attr("name"));

    $('#Poll1_BtnVote').click(function (e) {

        /* Step - 04:  */
        if ($("[name*='PollGroup']").filter(':checked').length == 0) {
            alert('Please select an option.');
            e.preventDefault();
        }

        /* Step - 05:  */
        $("[name*='PollGroup']").each(function () {
            $(this).attr('name', $(this).attr('ci-name'));
        });
    });
});

Шаг 1: Когда в ретрансляторе используется радиокнопка, его имя группы изменяется, поскольку asp.net меняет его, чтобы сделать его уникальным. Поэтому каждый переключатель получает другое имя группы (атрибут name в разметке на стороне клиента). Благодаря этому пользователь может одновременно выбрать все параметры. Эта проблема разрешается с помощью кода jquery, как объясняется последующими комментариями.

Шаг 2: Этот блок кода создает новый атрибут custome ci-name и копирует исходное значение атрибута name в этот новый настраиваемый атрибут. Этот процесс повторяется для каждого переключателя в опросе. Этот шаг поможет нам на более позднем этапе.

Шаг 3: Этот блок кода устанавливает значение атрибутов имени всех переключателей в опросе для значения атрибута имени первого переключателя. Этот шаг не позволяет пользователю выбирать более одного параметра за раз.

Шаг 4: Этот код внутри обработчика событий события нажатия кнопки голосования проверяет, проверял ли пользователь хотя бы один параметр. Если он этого не сделал, появится сообщение об ошибке.

Шаг 5: Этот код внутри обработчика событий события нажатия кнопки голосования устанавливает значение атрибута имени всех переключателей для их исходных значений. Это достигается путем копирования значения из пользовательского атрибута ci-name. Это позволяет серверному коду asp.net знать, какая кнопка была нажата.

Ответ 10

Я тоже был озадачен этой ошибкой и решил просто сбросить ретранслятор в пользу динамического построения таблицы с элементами управления внутри. В своем пользовательском элементе управления или на вашей странице просто добавьте следующие элементы:

<asp:Table ID="theTable" runat="server">
    <asp:TableHeaderRow runat="server">
        <asp:TableHeaderCell runat="server" Text="Column 1"/>
        <asp:TableHeaderCell runat="server" Text="Column 2"/>
        <asp:TableHeaderCell runat="server" Text="Column 3"/>
    </asp:TableHeaderRow>
</asp:Table>

Затем добавьте строки данных в код позади с помощью переключателей и других необходимых элементов управления. Конечно, вы можете сделать то же самое с другими элементами, такими как DIV:

<div runat="server" ID=theDiv">
</div>

Но давайте по-прежнему надеемся, что команда ASP.NET обойдется в устранении этой неудачной проблемы с помощью ретрансляторов и списков. Мне по-прежнему нравится управление ретранслятором и использую его, когда это возможно.

Ответ 11

Это чистый подход к серверной стороне с использованием отражения. Элемент RadioButton использует свойство UniqueGroupName для определения имени группы. Имя группы кэшируется внутри поля _uniqueGroupName. Установив это поле с помощью отражения, мы можем переопределить имя группы по умолчанию и использовать имя группы, которое одинаково для всех переключателей в ретрансляторе. Обратите внимание, что этот код должен быть запущен в событии "PreRender" элемента управления "RadioButton", чтобы гарантировать, что новое имя группы сохраняется в почтовых ящиках.

protected void rbOption_PreRender(object sender, EventArgs e)
{
    // Get the radio button.
    RadioButton rbOption = (RadioButton) sender;

    // Set the group name.
    var groupNameField = typeof(RadioButton).GetField("_uniqueGroupName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    groupNameField.SetValue(rbOption, "MyGroupName");

    // Set the radio button to checked if it was selected at the last post back.
    var groupValue = Request.Form["MyGroupName"];

    if(rbOption.Attributes["value"] == groupValue)
    {
        rbOption.Checked = true;
    } 
}

RadioButton исходный код: http://reflector.webtropy.com/default.aspx/Net/Net/[email protected]@[email protected]/DEVDIV/depot/DevDiv/releases/whidbey/netfxsp/ndp/fx/src/xsp/System/Web/UI/WebControls/[email protected]/2/[email protected]

Ответ 12

Это не может быть идеальным решением для всех, но я сделал следующее с помощью jQuery.

<asp:RadioButton ID="rbtnButton1" groupName="Group1" runat="server" /> <asp:RadioButton ID="rbtnButton2" groupName="Group1" runat="server" />

etc...

Затем включите следующий код на главной странице. (или всех ваших страниц)

$(function() {
//This is a workaround for Microsoft GroupName bug.  
//Set the radio button groupName attribute to make it work.
$('span[groupName] > input').click(function() {
    var element = this;
    var span = $(element).parent();
    if (element.checked) {
        var groupName = $(span).attr('groupName');
        var inputs = $('span[groupName=' + groupName + '] > input')
        inputs.each(function() {
            if (element != this)
                this.checked = false;
        });
    }
});

});

Ответ 13

Пользовательский контроль/переопределение для работы с методом HtmlInputControl.RenderAttributes(), игнорируя свойство RenderedNameAttribute:

/// <summary>
/// HACK:  For Microsoft&apos;s bug whereby they mash-up value of the "name" attribute.
/// </summary>
public class NameFixHtmlInputRadioButton : HtmlInputRadioButton
{
    protected override void RenderAttributes(HtmlTextWriter writer)
    {
        // BUG:  Usage of 'HtmlInputControl.RenderedNameAttribute'
        // writer.WriteAttribute("name", this.RenderedNameAttribute);
        writer.WriteAttribute(@"name", Attributes[@"Name"]);

        Attributes.Remove(@"name");

        var flag = false;
        var type = Type;

        if (! string.IsNullOrEmpty(type))
        {
            writer.WriteAttribute(@"type", type);
            Attributes.Remove(@"type");
            flag = true;
        }

        base.RenderAttributes(writer);

        if (flag && DesignMode)
        {
            Attributes.Add(@"type", type);
        }

        writer.Write(@" /");
    }
}

Ответ 14

Я использовал тот же Technic, чтобы снять отметку с другого радио с jquery, пожалуйста, найдите ниже код

<asp:RadioButton ID="rbSelectShiptoShop" runat="server" onchange="UnCheckRadio(this);" CssClass="radioShop" />

и script ниже

function UnCheckRadio(obj) {
           $('.radioShop input[type="radio"]').attr('checked', false);
           $(obj).children().attr('checked', true);
       }