ASP.NET:リピーターが生成したフォーム入力要素にアクセスする方法は?
-
05-07-2019 - |
質問
リピーターに多数のチェックボックスを生成させたい、例えば:
<tr><td><input type="checkbox" name="t" value="11cbf4deb87" /> <input type="checkbox" name="a" value="33cbf4deb87" />stackoverflow.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11cbf4deb88" /> <input type="checkbox" name="a" value="33cbf4deb87" />microsoft.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11cd3f33a89" /> <input type="checkbox" name="a" value="33cbf4deb87" />gmail.com</td></tr>
<tr><td><input type="checkbox" name="t" value="1138fecd337" /> <input type="checkbox" name="a" value="33cbf4deb87" />youporn.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11009efdacc" /> <input type="checkbox" name="a" value="33bf4deb87" />fantasti.cc</td></tr>
質問1:リピーターの実行中に各チェックボックスを個別に参照して、一意の値を設定するにはどうすればよいですか
次のようなものとデータバインドしますか
<itemtemplate>
<tr>
<td>
<input type="checkbox" name="t"
value="<%# ((Item)Container.DataItem).TangoUniquifier %>" />
<input type="checkbox" name="a"
value="<%# ((Item)Container.DataItem).AlphaUniquifier %>" />
<%# ((Item)Container.DataItem).SiteName %>
</td>
</tr>
</itemtemplate>
または、何らかの方法でOnItemDataBoundに設定することになっていますか?
<asp:repeater id="ItemsRepeater"
OnItemDataBound="ItemsRepeater_OnItemDataBound" runat="server">
...
<itemtemplate>
<tr>
<td>
<input id="chkTango" type="checkbox" name="t" runat="server" />
<input id="chkAlpha" type="checkbox" name="a" runat="server" />
<%# ((Item)Container.DataItem).SiteName %>
</td>
</tr>
</itemtemplate>
...
</asp:repeater>
protected void ItemsRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
// if the data bound item is an item or alternating item (not the header etc)
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// get the associated item
Item item = (Item)e.Item.DataItem;
//???
this.chkTango.Value = item.TangoUniquifier;
this.chkAlpha.Value = item.AlphaUniquifier;
}
}
しかし、分離コードで参照することになっている場合、分離コードでどのように参照しますか? <INPUT>
コントロールの(サーバー側)idプロパティを使用して参照することになっていますか?サーバー側のコントロールのIDは、クライアントに存在するIDと同じではないことに気付きました。
または<!> quot; t <!> quotという名前のINPUTコントロールを見つける必要がある場所で何かをする必要がありますか。 <!> quot; a <!> quot ;?という名前の別のまた、入力値を設定できるCheckBoxとはどのようなコントロールですか?
protected void ItemsRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
// if the data bound item is an item or alternating item (not the header etc)
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// get the associated item
Item item = (Item)e.Item.DataItem;
CheckBox chkTango = (CheckBox)e.Item.FindControl("chkTango");
chkTango.Value = item.TangoUniquifier;
CheckBox chkAlpha = (CheckBox)e.Item.FindControl("chkAlpha");
chkAlpha.Value = item.AlphaUniquifier;
}
}
質問2: ユーザーが後で「送信」をクリックしたときに、チェックされたすべてのチェックボックス、またはより具体的にはその値を見つけるにはどうすればよいですか?
FindControlが必要ですか?
protected void DoStuffWithLinks_Click(object sender, EventArgs e)
{
// loop through the repeater items
foreach (RepeaterItem repeaterItem in actionItemRepeater.Items)
{
Item item = repeaterItem.DataItem as Item;
// grab the checkboxes
CheckBox chkAlpha = (CheckBox)repeaterItem.FindControl("chkAlpha");
CheckBox chkTango = (CheckBox)repeaterItem.FindControl("chkTango");
if (chkAlpha.Checked)
{
item.DoAlphaStuff(chkAlpha.Name);
}
if (chkTango.Checked)
{
item.DoTangoStuff(chkTango.Name);
}
}
}
リピーター項目DataItemはクリックイベントハンドラーにまだありますか?
解決
入力コントロールをrunat = serverにする代わりに、サーバーコントロールを使用します
<asp:CheckBox id="whatever" runat="Server" />
ItemDataBoundに値を設定するときは、FindControlを使用します
CheckBox checkBox = (CheckBox)e.Item.FindControl("whatever");
checkBox.Checked = true;
アイテムを取得するときは、foreachコンストラクトのアイテムからFindControlも使用します。また、データバインドの方法によっては、ポストバック後にDataItemが存在しなくなる場合があります。
foreach (RepeaterItem item in myRepeater.Items)
{
if (item.ItemType == ListItemType.Item
|| item.ItemType == ListItemType.AlternatingItem)
{
CheckBox checkBox = (CheckBox)item.FindControl("whatever");
if (checkBox.Checked)
{ /* do something */ }
}
}
- 多くの人は、
as
演算子とFindControl()
を使用して「セーフキャスト」を試みています。フォームのコントロール名を変更すると、開発エラーを静かに無視して、追跡を難しくすることができるため、私はそれが好きではありません。コントロールが存在することが保証されていない場合にのみ、<=>演算子を使用しようとします。
の更新:どのCheckBoxがどちらですか?レンダリングされたhtmlでは、これらすべてのチェックボックス名が次のようになります
ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox
foreach item.FindControl()が名前を取得するため、名前が何であるかは気にしません。名前について何も想定しないでください。ただし、foreachを使用して反復する場合、通常はそれを参照して何かに戻す方法が必要です。ほとんどの場合、各CheckBoxにasp:HiddenFieldコントロールを配置して識別子を保持し、それを正しいエンティティに一致させることでこれを行います。
セキュリティに関する注意:隠しフィールドはJavaScriptで変更できるため、隠しフィールドの使用にはセキュリティ上の問題があります。この値は、フォームが送信される前にユーザーによって変更される可能性があることを常に意識してください。
他のヒント
CheckBoxListコントロールを使用する方が簡単な場合があります。
単純なケースでは、DataTextVieldとDataValueFieldをデータソースから取得した名前と値に設定し(データソースからデータを入力する場合)、それをバインドしてアイテムを作成します。
リピーターでチェックボックスを作成するよりも、おそらくあなたの側での作業が少なくなります。
隠しフィールドを処理するための特定のコードを次に示します。
MARKUP:
<asp:HiddenField ID="repeaterhidden" Value='<%# DataBinder.Eval(Container.DataItem, "value")%>' runat="server" >
C#:
{
HiddenField hiddenField = (HiddenField)item.FindControl(repeaterStringhidden);
{ /* do something with hiddenField.Value */
}
このKBが最良の答えをくれたと思います:
http://msdn.microsoft.com/en-us/library/ 1d04y8ss.aspx
幸運にも、これは.net 4.0バージョンでのみ利用可能だと思われます(3.5 SP1ではまだ動けません)。
引用(太字は私のもの):
コントロールの繰り返しインスタンスを生成するデータバインドコントロール内にコントロールがある場合、ASP.NETはコントロールの各インスタンスの UniqueIDおよびClientID値を生成します。 UniqueID値は、ネーミングコンテナのUniqueID値、コントロールのID値、および連続番号を組み合わせて生成されます。これは、DataList、 Repeater 、GridView、ListViewコントロールなどのコントロールの場合です。
ASP.NETは、ClientIDModeプロパティがAutoIDに設定されている場合、同様の方法でClientID値を生成します。通常、使用される連続番号の値を予測できないため、クライアントスクリプトでコントロールを参照するのが困難になる場合があります。クライアントスクリプトからデータバインドコントロールにアクセスする場合は、 ClientIDModeプロパティをPredictableに設定できます。これにより、ClientID値の予測が容易になります。
ClientIDModeをPredictableに設定すると、 ClientIDRowSuffixDataKeysプロパティを、データベーステーブルのプライマリキーなど、一意のデータフィールドの名前に設定することもできます。これにより、ASP.NETは、データキー値を予測できる場合、クライアントスクリプトで予測および参照しやすいクライアントIDを生成します。
したがって、バージョン3.5では、非表示フィールドを使用して実行しています。
foreach (RepeaterItem item in rptClientes.Items)
{
Panel pnl = (Panel)item.FindControl("divCliente");
Control c = pnl.FindControl("hdnID");
if (c is HiddenField)
{
if (((HiddenField)c).Value == hdnClienteNome.Value)
pnl.BackColor = System.Drawing.Color.Beige;
}
}