Подтвердить что ты не робот

Столбцы CheckBoxField в ASP.NET GridView отключены, даже если для ReadOnly установлено значение false

У меня есть GridView с двумя столбцами CheckBoxField. У обоих свойств ReadOnly установлено значение false, но для HTML-кода, сгенерированного для них, атрибут отключен = "отключен". Таким образом, значение не может быть изменено.

Сгенерированный пример HTML:

<span disabled="disabled"><input id="ctl00_ContentBody_GridView_ctl02_ctl01" type="checkbox" name="ctl00$ContentBody$GridView$ctl02$ctl01" checked="checked" disabled="disabled" /></span>

Кто-нибудь может сказать, как это понять?

4b9b3361

Ответ 1

Это по замыслу; строки в GridView по умолчанию не редактируются.

Есть два способа решить эту проблему:

1. Добавить ссылку редактирования

В свой тег GridView добавьте AutoGenerateEditButton="True". Когда ваш GridView визуализируется в браузере, вы должны найти гиперссылку с надписью "Изменить". Если вы щелкнете по нему, поля в вашем GridView станут редактируемыми, и ссылка "Изменить" станет двумя ссылками: одна для сохранения ваших изменений в базе данных, а другая для их отмены. Используя этот метод, вы можете выполнить всю работу по подключению изменений в GridView к базе данных, в зависимости от того, как вы делаете привязку данных. В этом примере используется элемент управления SqlDataSource.
alt text
(источник: philippursglove.com)

alt text

2. Добавьте TemplateField с CheckBox внутри него

Внутри тега <columns> вы можете добавить TemplateFields, для которых вы устанавливаете привязку данных, например,

<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 в какой-то момент, и вы захотите запустить его в правильном ряду! Вот два способа сделать это:

В свой тег 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;
    }
    ...
    }

Ответ 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));