36

テキストやその他のマークアップを一覧表示するテンプレートコントロール(リピーター)を入手しました。各アイテムにはラジオボタンが関連付けられており、ユーザーはリピーターによって作成されたアイテムの1つを選択できます。

リピーターは、デフォルトのASP.NET命名規則で生成されたIDと名前を設定するラジオボタンを書き込み、各ラジオボタンを完全な「グループ」にします。これは、すべてのラジオボタンが互いに独立していることを意味します。これも残念ながら、すべてのラジオボタンを同時に選択できることを意味します。ラジオボタンには、共通名を設定するために使用される巧妙な属性「groupname」があるため、それらはグループ化され、依存する必要があります(したがって、一度に1つしか選択できません)。問題は-これは機能しません-リピーターはIDと(グループ化を制御する)名前が異なることを確認します。

リピーター(リストビューまたはその他のテンプレート化されたデータバインドコントロールである可能性があります)を使用しているため、RadioButtonListを使用できません。それで、それは私をどこに残しますか?

私は以前にこの問題を抱えていて、それを解決したことを知っています。ほぼすべてのASP.NETプログラマーがそれを持っていたに違いないことを私は知っていますが、なぜ私はグーグルで問題の確実な解決策を見つけることができないのですか?JavaScriptによるグループ化を強制する(醜い!)、またはラジオボタンを非サーバーコントロールとして処理するソリューションに出くわしRequest.Form[name]、ステータスを読み取るように強制しました。また、イベントのname属性をオーバーライドしてみました。PreRender残念ながら、所有ページとマスターページは、完全なID /名を反映するためにこの名前を再度オーバーライドするため、同じ間違った結果になります。

私が投稿したものよりも優れた解決策がない場合でも、あなたの考えを投稿することは大歓迎です-少なくとも、私の友人の「ジャック」は、ASP.NETがめちゃくちゃになっていることがあることについて正しいことを知っています;)

4

14 に答える 14

9

ASP.NET Tip: Using RadioButton Controls in a Repeater

This is the code for the JavaScript function:

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;
}

The code is linked to the Repeater through the ItemDataBound event. For it to work properly, you need to know the name of the Repeater control, as well as the GroupName you're assigning to the RadioButtons. In this case, I'm using rptPortfolios as the name of the Repeater, and Portfolios as the group name:

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/

于 2009-01-01T20:13:03.080 に答える
7

Google-fu: asp.net ラジオボタン リピータの問題

確かに、IDマングリングの不幸な結果です。私の考えは、クライアントで同じ名前のサポートを追加するカスタム コントロールを作成するか、利用可能な多くのカスタム コントロールの 1 つを選択することです。

于 2008-12-18T10:20:31.977 に答える
6

私はjQueryスクリプトを使用します:

<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>
于 2010-08-29T10:59:58.400 に答える
6

Vladimir Smirnov は、この問題を解決する優れたカスタム コントロールを既に作成しています。プロジェクトでGroupRadioButtonを使用しており、リピーター内で作成されたラジオ ボタンと、リピーター外で作成されたラジオ ボタンがすべて同じグループの一部である場合、完全に機能しています。

于 2009-11-01T23:37:41.167 に答える
5

これが古い投稿であることは知っていますが、これがリストビューで行ったことです。私のリストビューは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
于 2011-05-04T12:50:47.550 に答える
3

これで少しはいいかも..

基本的にリピーター内のラジオボタンのセットであるユーザーコントロールがあります。ユーザーコントロールの各インスタンスには、インスタンスごとに一意の FilterTitle というパブリックプロパティがあります。

これら 2 つのプロパティをラジオボタンに追加し、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"
于 2010-05-10T23:42:39.010 に答える
2

完全を期すために、純粋な Javascript ソリューションを次に示します。

onclickこの属性を要素に追加するだけです ( GroupNameをあなたの GroupName にRadioButton置き換えます):RadioButton

<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>
于 2011-12-07T08:46:37.780 に答える
2

カスタム コントロールを作成し、UniqueID をリストビューの 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 属性のレンダリング方法のロジックを変更できます。ページ上の (リストビュー外の) 他のコントロールに固有の名前を維持するには、ListView から UniqueId を取得し、それに GroupName を追加して、それを RadioButton に追加します。

これにより、リストビュー内の異なる行で RadioButton をグループ化する際の問題が修正されます。通常の RadioButton のように動作するように、この機能をオン/オフするプロパティを含むロジックを追加することができます。

于 2013-01-22T00:13:34.360 に答える
1

私もこのバグに困惑し、内部にコントロールを備えたテーブルを動的に構築するために、リピーターを削除することにしました。ユーザーコントロールまたはページで、次の要素を追加するだけです。

<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チームが、リピーターとリストビューに関するこの不幸な問題の修正に取り掛かることを期待しましょう。私はまだリピーターコントロールが好きで、可能な限りそれを使用します。

于 2011-02-03T17:54:58.227 に答える
1

これは、リフレクションを使用した純粋なサーバー側のアプローチです。RadioButtonコントロールは、UniqueGroupNameプロパティを使用してグループ名を決定します。グループ名は_uniqueGroupNameフィールド内にキャッシュされます。リフレクションを使用してこのフィールドを設定することで、デフォルトのグループ名を上書きし、リピーターのすべてのラジオ ボタンで同じグループ名を使用できます。このコードは、「RadioButton」コントロールの「PreRender」イベントで実行して、新しいグループ名がポストバック間で保持されるようにする必要があることに注意してください。

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/3@5@50727@3053/DEVDIV/depot/DevDiv/releases/whidbey/netfxsp/ndp/fx/src/xsp/System /Web/UI/WebControls/RadioButton@cs/2/RadioButton@cs

于 2015-12-22T03:53:34.380 に答える
0

これは誰にとっても理想的な解決策ではないかもしれませんが、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's GroupName bug.  
//Set the radio button's 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;
        });
    }
});

});

于 2010-03-18T17:28:42.510 に答える
0

プロパティ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(@" /");
    }
}
于 2016-02-10T18:09:32.770 に答える
0

同じテクニックを使用して、jqueryで他のラジオのチェックを外しました。以下のコードを見つけてください

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

および以下のスクリプト

function UnCheckRadio(obj) {
           $('.radioShop input[type="radio"]').attr('checked', false);
           $(obj).children().attr('checked', true);
       }
于 2017-01-04T08:23:42.013 に答える