0

HtmlRadioButtons私は、ユーザーがチェックすることになっている、1つのテキストと複数のテキストでテーブル行を埋めるリピーターを持っています。リストは非常に大きくなる可能性があるため、最初のN行のみをチェックする必要があります。これをユーザーに示すために、最初のオプションの行の前に、説明テキストを含むTableRow1つTableCell(colspan = 4)を追加します。この行をリピーターに追加しItemDataBoundます。

ポストバックでは、追加の行を挿入する前の1つの項目を除いて、追加の行の前後のすべてのチェックされたラジオボタンがチェックされた値で戻ります追加の行( 、、および)のタイプを変更してみました。また、追加の行を変更してみました。ただし、この行/ラジオボタンでチェック値をポストバックすることはできません。常にfalseです。Html/RadioButtonHtml/TableRowHtml/TableCellEnableViewState

この値がポストバックしない理由を誰かが知っていますか?
ラジオボタンがポストバックするのを妨げずに行を追加する方法を知っている人はいますか?

追記:

  • OnClickすべての値を一度に処理して保存するのが好きなので、ラジオボタンにを追加したくありません。
  • 元のデータをにダウンロードしますPage_Loadが、他の行/ラジオボタンでは問題ないようです。

これは単純化された凝縮されたコードです。ASPX:

<ItemTemplate>
    <asp:TableRow runat="server">
        <asp:TableCell ID="CategoryName" CssClass="td_1" Text='<%# Eval("Name") %>'/>
        <asp:TableCell CssClass="td_radio" runat="server">
            <asp:HtmlInputRadioButton type="radio" runat="server"
              ID="rdBelonging"
              Name='<%# Eval("Id") %>'
              value='<%# (int)Enum_BelongsToCategory.Belonging %>'
              data-value='<%# Convert.ToBoolean(Eval("ShouldJudge")) ? "mandatory" : "optional" %>'/>
        </asp:TableCell>
        <asp:TableCell CssClass="td_radio" runat="server">
            <asp:HtmlInputRadioButton type="radio" runat="server"
              ID="rdNotBelonging"
              Name='<%# Eval("Id") %>'
              value='<%# (int)Enum_BelongsToCategory.NotBelonging %>'
              data-value='<%# Convert.ToBoolean(Eval("ShouldJudge")) ? "mandatory" : "optional" %>'/>
        </asp:TableCell>
        <%-- more Enum_BelongsToCategory-ReadioButtons... --%>
    </asp:TableRow>
</ItemTemplate>

行を追加するための背後にあるコード(このExperts-Exchange-post Repeater Control-別のテーブル行の追加に触発されました:

protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
        // first get item and show previous checks (if any)
        // ...
        if ( (lDataItem.ShouldJudge == false) && (_prevShouldJudge) ) {
            var lCell = new TableCell { ColSpan = 4, InnerText = "(minimum to check)" };
            var lRow = new TableRow();
            lRow.Cells.Add(lCell);
            e.Item.Controls.AddAt(0, lRow);
        }
        _prevShouldJudge = lDataItem.ShouldJudge;
    }
}

チェックされたラジオボタンを見つけるための背後にあるコード(システムブログのこのチーフに触発されて、aspnetでチェックされたラジオボタンを見つけます

private void SaveCategoryJudgements(Product product)
{
    int lRepeaterItemCount = 0;
    foreach (RepeaterItem lItem in repeaterCategories.Items) {
        lRepeaterItemCount ++;
        var lCheckedRadioButton = GetCheckedRadioButton(lItem.Controls);
        if (lCheckedRadioButton != null) {
            int lCategoryId;
            int lJudgement;
            if ( (int.TryParse(lCheckedRadioButton.Attributes["value"], out lJudgement)) 
              && (int.TryParse(lCheckedRadioButton.Name, out lCategoryId)) )
            {
                ClassificationData.SaveDocumentCategoryByUser(product, lCategoryId, (Enum_BelongsToCategory)lJudgement);
            }
        }
    }
}

public HtmlInputRadioButton GetCheckedRadioButton(ControlCollection controls)
{
    foreach (Control lControl in controls) {
        if (lControl is HtmlInputRadioButton) {
            var lRadioButton = (HtmlInputRadioButton)lControl;
            if (lRadioButton.Checked == true) 
            {
                return lRadioButton;
            }
        }
        else {
            var lRadioButton = GetCheckedRadioButton(lControl.Controls);
            if (lRadioButton != null) {
                return lRadioButton;
            }
        }
    }
    return null;
}
4

1 に答える 1

1

あなたの一般的なアプローチは正しいですが、IMO全体を複雑にしすぎているようです。

  1. サーバー側のテーブル コントロール、つまり: は必要ありません<asp:TableRow runat="server">。HTML コントロールではなくサーバー コントロールを使用すると、ViewStateが大幅に拡張されます。PostBack でリピーターを復元するために、.NET はすべてのサーバー コントロールを、クライアントに提供するページに格納されている隠しフィールドに保持する必要があることに注意してください。ここでは単純な html マークアップ、つまり:<td>で十分です。
  2. コード ビハインドで新しい行を追加するのではなく、可視性を false に設定した Panel コントロールを使用できます。リピーターをバインドすると、それを必要とする行に対して、パネルの可視性を true に設定できます。

上記のコードが必要な場合は、お尋ねください。喜んで提供いたします。

また、あなたの質問からは明らかではありませんが、表示するテキスト値は1 つだけですか (CategoryName)? その場合は、リピーターからこの部分を削除して、ラジオ ボタンのみを繰り返すことができます。

なぜラジオボタンを使用しているのですか?繰り返しますが、あなたの質問からは明らかではありませんが、あなたは次のように述べています:余分な行の前後のすべてのチェック済みラジオボタン。これは、ユーザーが複数のラジオ ボタンを選択できることを暗示しているようです。ラジオ ボタンの正しい使い方は、ユーザーに項目を1 つだけ選択させたい場合です。チェックボックスのリストは、ここで使用する正しいコントロールであるように思えます。

あなたが抱えている問題に関しては、ポストバックで動的に追加されたテーブル行を復元していないため、ViewState の復元が台無しになっている可能性が最も高いです。ViewState が正しく復元されるためには、ViewState が復元されるときに正確な数のコントロールが存在する必要があることに注意してください。更新パネルを使用する私の例に従えば、これで問題が軽減されるはずです。

編集

非表示のサーバー コントロールを追加すると機能し、新しいコントロールをコードに追加すると機能しない理由を理解するには、Viewstate の仕組みを理解する必要があります。詳細な説明については、ASP.NET ビュー ステートについてを参照してください。要するに、前に述べたように、ViewState が復元されたときに正確な数のコントロールが存在する必要があるため、可視性が false に設定されているサーバー コントロールがある場合、それらページがポストバックされ、ViewState が返されたときに存在します。復元されました。コードで追加する場合は、明示的に再追加する必要があります。その説明が理にかなっていることを願っています。

コード例:

<ItemTemplate>
    <tr>
        <td>'<%# Eval("Name") %>'</td>
        <td><asp:RadioButton ID="rdBelonging" ...</td>
        <!-- more Enum_BelongsToCategory-RadioButtons... -->
    </tr>
    <asp:Panel ID="pnlExplanationRow" runat="server" Visible="false">
    <tr>
        <td colspan=?>....</td>
    </tr>
    </asp:Panel>
</ItemTemplate>

HTH

于 2013-02-12T14:27:22.977 に答える