#c# #asp.net #gridview #datatable #newrow
Вопрос:
GridView содержит командное поле ShowDeleteButton вместе с другими полями текстового поля.
Я добавляю новую строку в эту сетку в C#, то есть добавляю новые текстовые поля для каждой вновь добавленной строки. Как добавить ссылку на удаление при добавлении новой строки?
<asp:Идентификатор GridView=»Gridview1″ runat=»сервер» ShowFooter=»истина» OnRowDataBound=»Gridview1_OnRowDataBound» OnRowDeleting=»Gridview1_RowDeleting» Автогенераторные столбцы=»ложь» ShowHeaderWhenEmpty=»Истина» Пустой текст=»Запись недоступна»> <asp:идентификатор GridView=»Gridview1″ runat=»сервер» ShowFooter=»истина» OnRowDataBound=»Gridview1_OnRowDataBound» OnRowDeleting=»Gridview1_RowDeleting» AutoGenerateColumns=»ложь» ShowHeaderWhenEmpty=»Истина» Пустой текст=»Запись недоступна»><asp:Заголовок поля шаблона=»Вопрос»> <asp:Заголовок поля шаблона=»Вопрос»><asp:Идентификатор текстового поля=»txtQuestion» runat=»сервер» Текст='<%# Eval(«Вопрос») %>'<%# Оценка(«Вопрос») %>><%# Оценка(«Вопрос») %>></asp:Текстовое поле> </asp:Текстовое поле></asp:Поле шаблонов>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" ReadOnly="true" Enabled="false" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text="Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="true" />
</Columns>
</asp:GridView>
private void AddNewRow()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new System.Data.DataColumn("Question", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("Answer", typeof(String)));
foreach (GridViewRow row in Gridview1.Rows)
{
TextBox txtQuestion = (TextBox)row.FindControl("txtQuestion");
TextBox txtAnswer = (TextBox)row.FindControl("txtAnswer");
dr = dt.NewRow();
dr[0] = txtQuestion.Text;
dr[1] = txtAnswer.Text;
dt.Rows.Add(dr);
}
dt.Rows.Add(dt.NewRow());
dt.Rows[dt.Rows.Count - 1]["Question"] = "";
dt.Rows[dt.Rows.Count - 1]["Answer"] = "";
dt.AcceptChanges();
Gridview1.EditIndex = dt.Rows.Count - 1;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
Ответ №1:
Я рекомендую вам просто добавить кнопку «Удалить» в каждую строку. Таким образом, пользователь может легко удалить строку.
Я также рекомендую вам загрузить сетку один раз с помощью таблицы данных, а затем добавить строку в таблицу данных, а НЕ в сетку.
Я мог бы написать кучу преимуществ этого подхода. Но некоторые преимущества заключаются в:
user does not get presented with multiple UI
user can edit any row on the grid - not have to hit edit, or save
a single un-do button can un-do all changes
a single SAVE button in ONE operation can save the WHOLE TABLE and change back to database
Ваш код для добавления строки и код для настройки и создания базы данных являются отдельными. Это означает, что вы можете изменить таблицу данных или даже указать источник таблицы из sql server. И, как уже отмечалось, это также позволяет сохранить ВСЮ таблицу ЦЕЛИКОМ. В результате пользователь может редактировать одну строку, много строк — вкладка вокруг ОЧЕНЬ похожа на электронную таблицу Excel. Когда это будет сделано, они смогут:
hit save - all data back to database
hit un-do - un-do all their edits
hit (add row) - add a new row to edit
hit delete key - it will delete the row in question (but UN-DO STILL ACTIVE!!!).
таким образом, у нас есть гораздо более приятный способ редактирования.
И поэтому я предлагаю вам не использовать встроенную кнопку удаления. Бросьте свою собственную кнопку — в любом случае она будет выглядеть приятнее. (и, следовательно, кнопка редактирования также не требуется!!!!).
Итак, вот наша разметка:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Question">
<ItemTemplate>
<asp:TextBox ID="txtQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text=" Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
Когда вы опускаете кнопку (я использовал кнопку с изображением), затем в редакторе кода сделайте это:
Обратите внимание, как СРАЗУ после нажатия «=» появляется intel-sense — выберите создать новое событие. Похоже, что НИЧЕГО не происходит, но если вы переключитесь на код позади, вы увидите, что был сгенерирован дополнительный код. Вы не можете дважды щелкнуть элементы управления внутри сетки, но вы МОЖЕТЕ создать событие щелчка для кнопки — или фактически любое событие для стандартного asp.net контролируйте таким образом.
Я также, чтобы спасти бедность в мире, также добавил пользовательский атрибут к этой кнопке под названием MyRowID — это установит индекс строки для этой кнопки.
Поскольку кнопка добавить новую строку находится за пределами сетки, мы можем просто дважды щелкнуть по этой кнопке и перейти к коду, стоящему за ней.
Теперь наш код выглядит следующим образом:
private DataTable MyTable = new DataTable();
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
ViewState["MyTable"] = MyTable;
}
else
MyTable = ViewState["MyTable"];
}
public void LoadGrid()
{
MyTable.Columns.Add(new DataColumn("Question", typeof(string)));
MyTable.Columns.Add(new DataColumn("Answer", typeof(string)));
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void btnAddNewQuestionnaire_Click(object sender, EventArgs e)
{
DataRow MyRow = MyTable.NewRow;
MyRow("Question") = "my question";
MyRow("Answer") = "my ans";
MyTable.Rows.Add(MyRow);
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
ImageButton btn = sender;
int RowID = btn.Attributes.Item("MyRowID");
MyTable.Rows(RowID).Delete();
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
Обратите внимание ОЧЕНЬ внимательно — мы добавили MyTable в класс формы. Таким образом, у нас есть сохраненная таблица, и мы работаем с этой таблицей.
На самом деле, ТОЧНО такое же приведенное выше определение можно использовать, если данные получены с SQL server. И не только БОЛЕЕ удивительно, но теперь мы можем таким образом СОХРАНИТЬ ОТПРАВИТЬ всю таблицу ОБРАТНО на sql server за одну операцию обновления. (вы просто зацикливаете сетку, возвращаете значения в таблицу и выполняете одно сохранение).
И выше нет кнопки грязного редактирования для редактирования строки. и я полагаю, что мы МОГЛИ бы добавить для дополнительных пометок поле для удаления — пользователь, если он нажмет или нажмет кнопку удаления, получит диалоговое окно подтверждения. Этот код может быть таким:
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>'
OnClientClick="return confirm('Delete this row?');"/>
Так что теперь, когда вы нажмете удалить строку, вы получите это:
Если вы нажмете » ОК » — он удалит — отменит — ничего не произойдет.
Таким образом, вы можете сэкономить много кода и сложности здесь с помощью:
Persist the data table
Pass the row ID with the button
use the intel-sense trick to wire up a separate and specific button event code.
Как уже отмечалось, весь этот описанный выше процесс ТАКЖЕ будет работать, если вы загрузите таблицу с данными с sql server — остальная часть кода «как есть» будет работать.
И чтобы сохранить данные обратно на sql server, вы можете, как уже отмечалось:
Извлеките данные из сетки обратно в эту сохраненную таблицу. А затем с помощью адаптера данных ОДНА команда обновления отправит все изменения обратно на sql server.