我正在制作一個模塊來將陣列保存在 SQL 資料庫中。例如,我要保存(889,4,01/12/2021),(889,4,02/12/2021)和(889,4,03/12/2021)。
我正在使用 gridview 獲取第一個值 ( 889)。然后我使用文本框獲取日期并運行查詢以回傳行中的日期并存盤在 gridview 中。
我正在嘗試使用 選擇第二個 gridview 值 ( date) GridView2.Rows[0].Cells[1].Text,但超出了有效值的范圍。
由于這是一個陣列,我將所有 SQL 陳述句保存在一個文本框中,稍后再執行,這就是我的代碼
string[,] arreglo = new string[GridView1.Rows.Count, 7];
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chkbox1 = (CheckBox)row.FindControl("chkActive");
if (chkbox1.Checked)
{
arreglo[row.RowIndex, 0] = GridView1.Rows[row.RowIndex].Cells[1].Text;
string[,] array = new string[GridView2.Rows.Count, 2];
foreach (GridViewRow col in GridView2.Rows)
array[col.RowIndex, 0] = GridView2.Rows[col.RowIndex].Cells[1].Text;
txtInsert.Text = txtInsert.Text "insert into T_USUARIO_dETALLE(id_usuario,campana,fecha,fecha_carga,id_superv,estado_dotacion) values ('" arreglo[row.RowIndex, 0].ToString() "', '" lblcampana.Text "','" GridView2.Rows[0].Cells[1].Text "','" LBLSUPERV.Text "','" ddlEstado.SelectedValue "')";
}
}
謝謝您的幫助!!!
uj5u.com熱心網友回復:
好的,所以這是 db land 中最經典的設定之一!
我們有一些父記錄,對于每條記錄,我們需要顯示(和編輯)子行。
現在有更多的 UI 選擇,然后是冰淇淋的口味。
這表明我們需要“嵌套”主記錄(比如在網格中)以顯示子記錄(我們的第二個網格)。
好吧,事實證明網格確實不能很好地嵌套。
因此,對于父記錄,讓我們使用 ListView - 它們作業得更好。
好的,所以我們可以啟動向導 - 構建 LV,然后在此處使用 NUCLEAR 武器并洗掉 炸毀所有模板。當我們添加這個時,洗掉額外的嵌套表。我計算 < 2 分鐘的時間。
所以,我們現在有了這個簡單的 LV。
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" >
<ItemTemplate>
<tr>
<td><asp:Button ID="cmdView" runat="server" Text=" " /></td>
<td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
<td><asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' /></td>
<td><asp:Label ID="ProvinceLabel" runat="server" Text='<%# Eval("Province") %>' /></td>
<td><asp:Label ID="DescriptionLabel" runat="server" Text='<%# Eval("Description") %>' /></td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class = "table table-hover" >
<tr runat="server" style="">
<th runat="server">View</th>
<th runat="server">HotelName</th>
<th runat="server">City</th>
<th runat="server">Province</th>
<th runat="server">Description</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
我們要填寫的代碼是這樣的:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadMainGrid();
}
void LoadMainGrid()
{
string strSQL = "SELECT * FROM tblHotels ORDER BY HotelName";
ListView1.DataSource = MyRst(strSQL);
ListView1.DataBind();
}
我們現在有這個:

好的,現在我們需要子網格。
然后我們將這個子網格移動到上面的LV中。
所以,現在我們有了這個標記:
<td><asp:Label ID="DescriptionLabel" runat="server" Text='<%# Eval("Description") %>' /></td>
</tr>
<tr>
<td colspan="5">
<div id="MyGrid" runat="server" style="display:none;margin-left:1%">
<div>
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table table-hover table-responsive borderhide" >
<Columns>
<asp:TemplateField HeaderText="First Name">
<ItemTemplate>
<asp:TextBox ID="FirstName" runat="server" Text='<%# Eval("FirstName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Last Name">
<ItemTemplate>
<asp:TextBox ID="LastName" runat="server" Text='<%# Eval("LastName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:TextBox ID="City" runat="server" Text='<%# Eval("City") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Start date">
<ItemTemplate>
<asp:TextBox ID="dtStart" runat="server" Text='<%# Eval("dtStart", "{0:yyyy-MM-ddTHH:mm}") %>' TextMode="DateTimeLocal" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="End date">
<ItemTemplate>
<asp:TextBox ID="dtEnd" runat="server" Text='<%# Eval("dtEnd","{0:yyyy-MM-ddTHH:mm}") %>' TextMode="DateTimeLocal" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<div style="float:right;margin-right:-10px">
<asp:Button ID="cmdSave" runat="server" Text="Save Edits" CssClass="btn" OnClick="cmdSave_Click" />
<asp:Button ID="cmdAdd" runat="server" Text="Add New Row" CssClass="btn" style="margin-left:5px" OnClick="cmdAdd_Click" />
</div>
</div>
</td>
所以我們在 lv 列的標記之后直接進入上面。
現在,我們要做的就是連接“ ”按鈕以展開:
那是LV的第一排按鈕
<td><asp:Button ID="cmdView" runat="server" Text=" " OnClick="cmdView_Click"/></td>
代碼是這樣的:
protected void cmdView_Click(object sender, EventArgs e)
{
Button cmd = (Button)sender;
ListViewDataItem gVR = (ListViewDataItem)cmd.NamingContainer;
GridView gChild = (GridView)gVR.FindControl("GridView2"); // pluck out the grid for this row
HtmlGenericControl MyDiv = (HtmlGenericControl)gVR.FindControl("MyGrid");
//if (gChild.Style["display"] == "normal")
if (MyDiv.Style["display"] == "normal")
{
// if grid is already display, then hide it, and exit
MyDiv.Style["display"] = "none";
return;
}
MyDiv.Style["display"] = "normal";
int HotelPK = (int)ListView1.DataKeys[gVR.DataItemIndex]["ID"];
// only re-load if never loaded
if (gChild.Rows.Count == 0)
{
gChild.DataSource = MyRst("SELECT * from People where hotel_id = " HotelPK);
gChild.DataBind();
}
}
所以,現在我們有這個:

好的,現在我們要做的就是創建一個“保存”按鈕來保存我們對這個 GV 所做的任何更改。
這很容易,所以我們放入一個像這樣的保存按鈕:
所以,在我們的網格正下方,我們放入這個:
</asp:GridView>
</div>
<div style="float:right;margin-right:-10px">
<asp:Button ID="cmdSave" runat="server" Text="Save Edits" CssClass="btn" />
<asp:Button ID="cmdAdd" runat="server" Text="Add New Row" CssClass="btn" style="margin-left:5px" />
</div>
</div>
我們現在有這個:

Ok, so for the button, we add a click event:

(just type in onclick= and intelsense will offer to create the click event, looks like nothing occurred, but going to code behind, you will see the even stub.
And we use this code:
protected void cmdSave_Click(object sender, EventArgs e)
{
Button cmdSave = (Button)sender;
ListViewDataItem lvRow = (ListViewDataItem)cmdSave.NamingContainer;
GridView MyGrid = (GridView)lvRow.FindControl("GridView2");
int HotelID = (int)ListView1.DataKeys[lvRow.DisplayIndex]["ID"];
// send grid to table
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * from People WHERE hotel_id = " HotelID;
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
DataTable rstGrid = new DataTable();
rstGrid.Load(cmdSQL.ExecuteReader());
foreach (GridViewRow gRow in MyGrid.Rows)
{
DataRow OneRow = rstGrid.Rows[gRow.RowIndex];
OneRow["FirstName"] = ((TextBox)gRow.FindControl("FirstName")).Text;
OneRow["LastName"] = ((TextBox)gRow.FindControl("LastName")).Text;
OneRow["City"] = ((TextBox)gRow.FindControl("City")).Text;
string myDate = ((TextBox)gRow.FindControl("dtStart")).Text;
if (myDate == "")
OneRow["dtStart"] = DBNull.Value;
else
OneRow["dtStart"]= DateTime.ParseExact(myDate, "yyyy-MM-ddTHH:mm", null);
myDate = ((TextBox)gRow.FindControl("dtEnd")).Text;
if (myDate == "")
OneRow["dtEnd"] = DBNull.Value;
else
OneRow["dtEnd"] = DateTime.ParseExact(myDate, "yyyy-MM-ddTHH:mm", null);
}
da.Update(rstGrid);
}
}
}
Ok, we might as well wire up the "new row button".
so for that code we have this:
protected void cmdAdd_Click(object sender, EventArgs e)
{
Button cmdNew = (Button)sender;
ListViewDataItem lvRow = (ListViewDataItem)cmdNew.NamingContainer;
GridView MyGrid = (GridView)lvRow.FindControl("GridView2");
int HotelID = (int)ListView1.DataKeys[lvRow.DisplayIndex]["ID"];
string strSQL = "INSERT INTO People (Hotel_ID) VALUES(" HotelID ")";
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
cmdSQL.ExecuteNonQuery();
}
DataTable rstGrid = MyRst("SELECT * from People where Hotel_ID = " HotelID);
MyGrid.DataSource = rstGrid;
MyGrid.DataBind();
}
}
I also have a helper routine - its a global function, and that just returns a data table for a given sql string. I did use that a few times in above.
This routine:
public DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
Edit/Upate (making the UI better):
One issue? If a user hits add new row, they will no doubt start typing, and then VERY likly hit add new row again (but with above, they MUST hit save data first).
so, I suggest a SAVE data before adding a new row.
This forces us to break out that longer routine anyway.
所以我們添加一個“Grid to Table”,然后一個“save table”到資料庫。將其分為兩個步驟不僅修復了上述“錯誤”或“問題”,而且實際上代碼更少。
因此,我建議更新這 3 個(以及 4 個)例程,它們都更短,應該使用。
因此,添加行、保存編輯和 MyRst 都已更新。
我建議使用此代碼,因此如果用戶點擊添加行,他們將不會丟失任何我敢說很可能會發生的現有編輯。
因此,我建議將此代碼用于保存和添加行按鈕
protected void cmdSave_Click(object sender, EventArgs e)
{
Button cmdSave = (Button)sender;
ListViewDataItem lvRow = (ListViewDataItem)cmdSave.NamingContainer;
GridView MyGrid = (GridView)lvRow.FindControl("GridView2");
int HotelID = (int)ListView1.DataKeys[lvRow.DisplayIndex]["ID"];
DataTable rstGrid = MyRst("SELECT * FROM People WHERE Hotel_ID = " HotelID);
// send grid to table
GridToTable(MyGrid, rstGrid);
// save to database
SaveGrid(MyGrid, rstGrid);
}
protected void cmdAdd_Click(object sender, EventArgs e)
{
Button cmdNew = (Button)sender;
ListViewDataItem lvRow = (ListViewDataItem)cmdNew.NamingContainer;
GridView MyGrid = (GridView)lvRow.FindControl("GridView2");
int HotelID = (int)ListView1.DataKeys[lvRow.DisplayIndex]["ID"];
DataTable rstGrid = MyRst("SELECT * FROM People where Hotel_ID = " HotelID);
// send any data edits from Grid to table
GridToTable(MyGrid, rstGrid);
// add new row
DataRow MyNewRow = rstGrid.NewRow();
MyNewRow["Hotel_ID"] = HotelID;
rstGrid.Rows.Add(MyNewRow);
MyGrid.DataSource = rstGrid;
MyGrid.DataBind();
// save data (must do AFTER grid bind - new row!!!)
SaveGrid(MyGrid, rstGrid);
}
void SaveGrid(GridView MyGrid, DataTable rstGrid)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(rstGrid.TableName, conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstGrid);
}
}
}
void GridToTable(GridView MyGrid, DataTable rstGrid)
{
foreach (GridViewRow gRow in MyGrid.Rows)
{
DataRow OneRow = rstGrid.Rows[gRow.RowIndex];
OneRow["FirstName"] = ((TextBox)gRow.FindControl("FirstName")).Text;
OneRow["LastName"] = ((TextBox)gRow.FindControl("LastName")).Text;
OneRow["City"] = ((TextBox)gRow.FindControl("City")).Text;
string myDate = ((TextBox)gRow.FindControl("dtStart")).Text;
if (myDate == "")
OneRow["dtStart"] = DBNull.Value;
else
OneRow["dtStart"] = DateTime.ParseExact(myDate, "yyyy-MM-ddTHH:mm", null);
myDate = ((TextBox)gRow.FindControl("dtEnd")).Text;
if (myDate == "")
OneRow["dtEnd"] = DBNull.Value;
else
OneRow["dtEnd"] = DateTime.ParseExact(myDate, "yyyy-MM-ddTHH:mm", null);
}
}
public DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
rstData.TableName = strSQL;
}
}
return rstData;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/369804.html
