2つのCheckBoxField列を持つGridViewがあります。どちらもReadOnlyプロパティがfalseに設定されていますが、それらに対して生成されたHTMLコードには、disabled = "disabled"属性があります。したがって、値は変更できません。
生成されたHTMLの例:
<span disabled="disabled"><input id="ctl00_ContentBody_GridView_ctl02_ctl01" type="checkbox" name="ctl00$ContentBody$GridView$ctl02$ctl01" checked="checked" disabled="disabled" /></span>
誰かがそれを理解する方法を言うことができますか?
これは仕様によるものです。 GridViewの行は、デフォルトでは編集できません。
これに対処する方法は2つあります。
GridViewタグで、AutoGenerateEditButton="True"
を追加します。 GridViewがブラウザーでレンダリングされると、「編集」というラベルの付いたハイパーリンクが表示されます。これをクリックすると、GridViewのフィールドが編集可能になり、[編集]リンクは2つのリンクになり、1つはデータベースへの変更を保存するためのリンクで、もう1つはそれらを破棄するためのリンクです。この方法を使用すると、データバインディングの実行方法に応じて、GridViewでの変更をデータベースに結び付けるためのすべての配管を行うことができます。この例では、SqlDataSourceコントロールを使用しています。
(ソース: philippursglove.com )
<columns>
タグ内に、データバインディングを設定するTemplateFieldを追加できます。
<asp:TemplateField HeaderText="Discontinued">
<ItemTemplate>
<asp:CheckBox runat="server" ID="DiscontinuedCheckBox"
Checked='<%# Eval("Discontinued") %>' AutoPostback="true"
OnCheckedChanged="DiscontinuedCheckBox_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
(ソース: philippursglove.com )
このチェックボックスは有効になりますが、変更をデータベースに反映するには、自分で作業を行う必要があります。ある時点でUPDATE
ステートメントを実行する必要があり、正しい行で実行したいので、データベースキーを取得できる限り、これは簡単です。これを行うには、次の2つの方法があります。
GridviewタグにDataKeyNames="MyDatabasePrimaryKey"
を追加します。次に、CheckedChanged
イベントハンドラーで、どの行にいるかを調べ、DataKeys
配列でその行を検索する必要があります。
protected void DiscontinuedCheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox DiscontinuedCheckBox;
SqlConnection conn;
SqlCommand cmd;
int productId;
GridViewRow selectedRow;
// Cast the sender object to a CheckBox
DiscontinuedCheckBox = (CheckBox)sender;
// We can find the row we clicked the checkbox in by walking up the control tree
selectedRow = (GridViewRow)DiscontinuedCheckBox.Parent.Parent;
// GridViewRow has a DataItemIndex property which we can use to look up the DataKeys array
productId = (int)ProductGridView.DataKeys[selectedRow.DataItemIndex].Value;
using (conn = new SqlConnection(ProductDataSource.ConnectionString))
{
cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
if (DiscontinuedCheckBox.Checked)
{
cmd.CommandText = "UPDATE Products SET Discontinued = 1 WHERE ProductId = " + ProductId.ToString();
}
else
{
cmd.CommandText = "UPDATE Products SET Discontinued = 0 WHERE ProductId = " + ProductId.ToString();
}
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
または、HiddenFieldコントロールにキーを追加することもできます。
<asp:TemplateField HeaderText="Discontinued">
<ItemTemplate>
<asp:hiddenfield runat="server" id="ProductIdHiddenField"
Value='<%# Eval("ProductID") %>' />
<asp:CheckBox runat="server" ID="DiscontinuedCheckBox"
Checked='<%# Eval("Discontinued") %>'
AutoPostback="true"
OnCheckedChanged="DiscontinuedCheckBox_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
コード:
protected void DiscontinuedCheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox DiscontinuedCheckBox;
HiddenField ProductIdHiddenField;
DiscontinuedCheckBox = (CheckBox)sender;
ProductIdHiddenField = (HiddenField)DiscontinuedCheckBox.Parent.FindControl("ProductIdHiddenField");
using (conn = new SqlConnection(ProductDataSource.ConnectionString))
{
...
if (DiscontinuedCheckBox.Checked)
{
cmd.CommandText = "UPDATE Products SET Discontinued = 1 WHERE ProductId = " + ProductIdHiddenField.Value;
}
...
}
PhilPursgloveソリューションが機能します(ネストされたgrivviewでも)。ありがとうございました!
私の完全なコード(動的な作成のためにnetestグリッドビューに直接アクセスできないため、コントロールツリーを使用してgrivviewも取得するように変更されました):
protected void Cb_IsApprovedByManagement_CheckChanged(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
// find the row we clicked the checkbox in by walking up the control tree
GridViewRow selectedRow = (GridViewRow)cb.Parent.Parent;
GridView gridView = (GridView)selectedRow.Parent.Parent;
// look up the DataKeys array
int QuestionID_Current = (int)gridView.DataKeys[selectedRow.DataItemIndex].Value;
// change value
QuestionManager.ToggleActivity(QuestionManager.GetQuestion(QuestionID_Current));