Кнопка Удаления Вида Сетки — Ошибка Ссылки На Объект

#c# #asp.net #gridview #webforms

Вопрос:

Я пытаюсь разработать веб-страницу в asp .NET с помощью GridView. Я хочу, чтобы в представлении сетки была кнопка редактирования и удаления. Ниже приведена моя разметка для GridView:

 <asp:GridView ID="EduGrid" CssClass="edugrid table table-striped table-hover table-borderless" runat="server" AutoGenerateColumns="False" GridLines="None" OnRowDeleted="EduGrid_RowDeleted" OnRowDeleting="EduGrid_RowDeleting">
    <Columns>
                 <asp:CommandField SelectText="" ShowSelectButton="True" ControlStyle-CssClass="btn btn-dark btn-sm fa fa-edit" />
                 <asp:CommandField DeleteText="" ShowDeleteButton="true" ControlStyle-CssClass="btn btn-dark btn-sm fa fa-trash" />
                 <asp:BoundField DataField="degree" HeaderText="Degree" SortExpression="degree" />
                 <asp:BoundField DataField="major" HeaderText="Major" SortExpression="major" />
                 <asp:BoundField DataField="year" HeaderText="Passing Year" SortExpression="year" />
                 <asp:BoundField DataField="total marks" HeaderText="Total Marks" SortExpression="total marks" />
                 <asp:BoundField DataField="obt marks" HeaderText="Obtained Marks" SortExpression="obt marks" />
                 <asp:BoundField DataField="division" HeaderText="Division" SortExpression="division" />
                 <asp:BoundField DataField="board" HeaderText="Board/University" SortExpression="board" />
    </Columns>
                                
    <HeaderStyle CssClass="thead-dark" Font-Names="Calibri" Font-Size="Larger" />
    <RowStyle Font-Names="calibri" Font-Size="Medium" />
</asp:GridView>
 

У меня также есть метка на странице «Откровенный», которая содержит идентификатор для получения записей в GridView и удаления записей из базы данных. Но, поскольку для каждого кандидата более 1 записи, я хочу удалить записи на основе 2 параметров, т. е. ID и степени (первый столбец). Он удаляет только на основе идентификатора, но удаляет все записи с этим конкретным идентификатором, но я хочу удалить только одну конкретную запись. Если я укажу столбец степени в качестве параметра, это приведет к исключению ссылки на объект. Ниже приведен мой внутренний код на c#:

         protected void EduGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            GridViewRow row = EduGrid.SelectedRow;
            conn = new SqlConnection(connString);
            string query = "DELETE FROM [Edu Info] WHERE cnic = @cnic AND degree = @degree";
            sqlcmd = new SqlCommand(query, conn);
            sqlcmd.Parameters.AddWithValue("@cnic", lblID.Text);
            sqlcmd.Parameters.AddWithValue("@degree", row.Cells[1].Text);

            try
            {
                conn.Open();
                sqlcmd.ExecuteNonQuery();
                lblInfo.Text = "Record deleted successfully.";
                lblInfo.Visible = true;
                Get_Edu();
            }

            catch (Exception ex)
            {
                lblInfo.Text = "An error occurred. Please contact the administrator.";
                lblInfo.Visible = true;
            }

            finally
            {
                conn.Close();
                conn.Dispose();
                SqlConnection.ClearAllPools();
            }
        }
 

Я думаю, проблема в том, что метод OnRowDeleting не подходит для работы с GridView.Выбранное место и все такое .selectedRow может работать только в методе OnSelectedIndexChanged. Если это так и я прав, что мне следует сделать, чтобы это исправить? Кто-нибудь может, пожалуйста, предложить решение?

Спасибо.

Комментарии:

1. Взгляните на мой учебник . Он охватывает все основы редактирования и обновления GridView. Вы можете скачать демо-проект с GitHub , чтобы начать работу.

2. в нем нет моего ответа @VDWWD. пожалуйста, дайте ответ относительно моей проблемы.

3. Да, это так. Вы смотрели на GridView_RowDeleting это ? Оно имеет e.RowIndex .

Ответ №1:

Ладно, здесь много проблем. И мне не понятно, почему ваш источник данных НЕ включает первичный ключ базы данных. И в результате вам не нужно будет использовать как cnic, так и степень для идентификации строки. Я никогда не мог припомнить, чтобы в сетке были строки, в которых у меня нет идентификатора ПК. (так что, очень странно с вашей стороны).

Однако имейте в виду, что событие удаления НЕ изменяет выбранный индекс. На самом деле, если вы нажмете, скажем, кнопку, используйте CommandName/CommandText, вы обнаружите, что сначала срабатывает команда строки (выбранный индекс еще не изменен), а ЗАТЕМ срабатывает событие выбранного индекса.

В вашем примере — индекс не изменится.

Однако в этом случае вы можете нажать на строку с помощью этого:

 e.RowIndex
 

Итак, теперь вы можете пойти вот так:

 GridViewRow row = EduGrid.Rows[e.RowIndex];
 

Итак, все остальное, что у вас есть, должно быть в порядке. Итак, просто имейте в виду, что для командных кнопок и большинства кнопок в сетке выбранный индекс даже (если он должен был сработать) фактически срабатывает ПОСЛЕ заглушки события кнопки. В некоторых случаях теоретически вы могли бы переместить код в выбранное событие изменения индекса, но в этом случае это даже не срабатывает. Таким образом, выбранный индекс НЕДОСТУПЕН. Используйте e.RowIndex, чтобы получить эту строку.

Кроме того, если вы включаете PK из базы данных, вам не нужно использовать два столбца для идентификации этой строки в базе данных, а ТОЛЬКО идентификатор строки PK. И вам не нужно, чтобы ПК даже отображался в сетке.

Вот для чего нужны имена данных = «имя столбца строки PK»»

напр.:

     <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
            DataKeyNames="ID" >
 

Итак, имена данных = «PK ИЗ базы данных»

Таким образом, в приведенном выше событии разделения строк, затем

 e.RowIndex - gets you row index clicked on
e.Keys["ID"]  - gets you database PK
 

Итак, обратите внимание, как вы можете (должны) попытаться установить имена данных = «первичный ключ» из базы данных. затем вы можете получить с помощью электронных ключей[«ИДЕНТИФИКАТОР»] идентификатор строки PK.

Комментарии:

1. спасибо за подробный ответ, @Albert D. kallal. Причина, по которой у меня нет PK в моем источнике данных, заключается в том, что клиент не хочет, чтобы он был в сетке. Кроме того, я решил эту проблему, используя ваш ответ, добавив степень в качестве имени данных. Спасибо за помощь !

2. Это хорошо! Так вот для чего нужны данные! Вам не нужно выставлять или когда — либо показывать PK-даже в разметке. Если вы зададите имена данных=»ИДЕНТИФИКАТОР»? Тогда вы в полной мере используете значения PK, но они никогда не отображаются в сетке, и вы никогда не предоставляете их на стороне клиента. Итак, для безопасности и простоты использования значений строк PK? Данные-это ваш полет на ковре-самолете.

3. Да, я тоже понял это из твоего ответа. Теперь я использую PK в качестве источника данных, но не показываю его в сетке.