web-dev-qa-db-ja.com

ReadOnlyがfalseに設定されていても、ASP.NET GridViewのCheckBoxField列が無効になっている

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>

誰かがそれを理解する方法を言うことができますか?

25
brain_pusher

これは仕様によるものです。 GridViewの行は、デフォルトでは編集できません。

これに対処する方法は2つあります。

1.編集リンクを追加する

GridViewタグで、AutoGenerateEditButton="True"を追加します。 GridViewがブラウザーでレンダリングされると、「編集」というラベルの付いたハイパーリンクが表示されます。これをクリックすると、GridViewのフィールドが編集可能になり、[編集]リンクは2つのリンクになり、1つはデータベースへの変更を保存するためのリンクで、もう1つはそれらを破棄するためのリンクです。この方法を使用すると、データバインディングの実行方法に応じて、GridViewでの変更をデータベースに結び付けるためのすべての配管を行うことができます。この例では、SqlDataSourceコントロールを使用しています。
alt text
(ソース: philippursglove.com

alt text

2. CheckBoxを含むTemplateFieldを追加します

<columns>タグ内に、データバインディングを設定するTemplateFieldを追加できます。

<asp:TemplateField HeaderText="Discontinued">  
    <ItemTemplate>  
        <asp:CheckBox runat="server" ID="DiscontinuedCheckBox" 
            Checked='<%# Eval("Discontinued")  %>' AutoPostback="true" 
            OnCheckedChanged="DiscontinuedCheckBox_CheckedChanged" />  
    </ItemTemplate>  
</asp:TemplateField>

alt text
(ソース: 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;
    }
    ...
    }
41
PhilPursglove

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));
1
J_Reed