ASP.NET GridView 中的 CheckBoxField 列被禁用,即使 ReadOnly 设置为 false

Posted

技术标签:

【中文标题】ASP.NET GridView 中的 CheckBoxField 列被禁用,即使 ReadOnly 设置为 false【英文标题】:CheckBoxField columns in ASP.NET GridView are disabled even if ReadOnly set to false 【发布时间】:2011-03-06 07:02:25 【问题描述】:

我有一个带有两个 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>

谁能告诉我怎么解决?

【问题讨论】:

【参考方案1】:

这是设计使然;默认情况下,GridView 中的行不可编辑。

有两种方法可以解决这个问题:

1。添加编辑链接

在您的 GridView 标记中,添加 AutoGenerateEditButton="True"。当您的 GridView 在浏览器中呈现时,您现在应该找到一个标有“编辑”的超链接。如果单击它,GridView 中的字段将变为可编辑,并且 Edit 链接将变为两个链接,一个用于将更改保存到数据库,另一个用于丢弃它们。使用此方法,可以为您完成将 GridView 中的更改连接到数据库的所有管道,具体取决于您进行数据绑定的方式。此示例使用 SqlDataSource 控件。(来源:philippursglove.com)

2。添加一个带有 CheckBox 的 TemplateField

&lt;columns&gt; 标签内,您可以添加您自己设置数据绑定的模板字段,例如

<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 语句并且您希望在正确的行上运行它!有两种方法可以做到这一点:

在您的 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;
    
    ...
    

【讨论】:

谢谢,你的回答很有用。我喜欢第二个变体,但在这种情况下,更改复选框的值会导致页面重新加载并且数据再次绑定到网格,因此值会变回。如何解决? @brain_pusher 还没有忘记你,明天会看到如何解决这个问题! @PhilPursglove 我知道这是一个旧线程,但我正在使用它并遇到了同样的问题。我找到的解决方案是在aspx文件中将AutoPostBack改为false。【参考方案2】:

PhilPursglove 解决方案对我有用(即使在嵌套的 grivview 中)。谢谢!

我的完整代码(修改为使用控制树也获得 grivview,因为动态创建我无法直接访问 netest gridview):

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

【讨论】:

以上是关于ASP.NET GridView 中的 CheckBoxField 列被禁用,即使 ReadOnly 设置为 false的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 中 GridView 中的 PageIndexChanging

通过asp.net中的数据表在asp gridview中添加按钮列

在 asp.net 中处理 Gridview 控件中的文本框?

从 ASP.NET GridView 更新中获取 textarea 中的文本

使用VB在ASP.Net中对GridView中的事件进行排序

更新asp.net GridView中的行时出错