iT邦幫忙

0

[C#] GridView編輯時,自動修改Textbox欄位值

抱歉遇到一個問題排除不了,想詢問一下
在GridView1 編輯時,要變更TextBox1、TextBox2的值
TextBox1、TextBox2原本都是有值的
語法如下

protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
  DateTime dt = DateTime.Now;
  string nowDate = dt.ToString("yyyy-MM-dd");
  string nowTime = dt.ToString("HH:mm:ss");
  TextBox TB1 = (TextBox)GridView1.Rows[e.NewEditIndex].FindControl("TextBox1");
  TextBox TB2 = (TextBox)GridView1.Rows[e.NewEditIndex].FindControl("TextBox2");
  TB1.Text = nowDate; 
  TB2.Text = nowTime; 
}

但按下編輯時會出現 "並未將物件參考設定為物件的執行個體。"
錯誤點在 TB1.Text = nowDate; 開始

請問這一句錯的點在哪邊?
謝謝

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
glj8989332
iT邦研究生 4 級 ‧ 2020-08-21 16:21:08
最佳解答

應該有指定TextBox1TextBox2的ID給那兩個輸入框吧~?

目前我寫的範例可以取到這兩個輸入框, aspx的宣告如下, 而.cs程式跟你一樣.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowEditing="GridView1_RowEditing">
	 <Columns>
		 <asp:TemplateField HeaderText="Id">
			 <ItemTemplate>
				<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("Id") %>'></asp:TextBox>
			</ItemTemplate>
		 </asp:TemplateField>
		 <asp:TemplateField HeaderText="Name">
			<ItemTemplate>
				<asp:TextBox ID="TextBox2" runat="server" Text='<%# Eval("Name") %>'></asp:TextBox>
			</ItemTemplate>
		 </asp:TemplateField>
		 <asp:CommandField ShowEditButton="True" />
	 </Columns>
 </asp:GridView>

2020/08/25 更新

後續大大提供的Code是用EditItemTemplate, 所以在RowUpdating無法直接取到元件, 必須改在RowDataBound使用. 要觸發RowDataBound是要有GridView1.DataBind()被呼叫~

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
	if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowState == DataControlRowState.Edit)
	{
		if (e.Row.RowIndex == GridView1.EditIndex)
		{
			 string nowDate = dt.ToString("yyyy-MM-dd");
			 string nowTime = dt.ToString("HH:mm:ss");
			 TextBox TB1 = (TextBox)e.Row.FindControl("TextBox1");
			 TextBox TB2 = (TextBox)e.Row.FindControl("TextBox2");
			 TB1.Text = nowDate; 
			 TB2.Text = nowTime; 
		}
	}
}
看更多先前的回應...收起先前的回應...
阿偉 iT邦新手 2 級 ‧ 2020-08-21 16:50:32 檢舉

我的TextBox1和TextBox2在編輯前都是有值的
會不會是這原因?

glj8989332 iT邦研究生 4 級 ‧ 2020-08-21 17:20:27 檢舉

既然出現了 [並未將物件參考設定為物件的執行個體]錯誤訊息, 肯定是TB1是空值, 可以用中斷點查看....所以才問是不是ID給錯而抓不到~

阿偉 iT邦新手 2 級 ‧ 2020-08-24 13:22:13 檢舉

Empty "產生的列舉型別沒有結果" string
但Textbox編號確實沒錯...見鬼了

阿偉 iT邦新手 2 級 ‧ 2020-08-24 13:28:06 檢舉

我表單是這樣設計
我在同一頁有DetailsView1 << 新增資料用
有一個GridViewRow2 <<查詢料號,選取會帶入基本資料到DetailsView1
DetailsView1上其中兩格,如本問題假設為TextBox1和TextBox2
在Page_Load的時候,會帶入當下的日期、時間到

DetailsView1新增完畢後,GridViewRow2會顯示本日新增的項目
在GridViewRow2樣板內,日期、時間假設也是TextBox1和TextBox2
有確認過GridViewRow2內的日期和時間編號沒錯
所以才有我上述描述語法

下方確實取不到TB1和TB2的值,莫非是e.NewEditIndex 這邊有問題?

TextBox TB1 = (TextBox)GridView1.Rows[e.NewEditIndex].FindControl("TextBox1");
TextBox TB2 = (TextBox)GridView1.Rows[e.NewEditIndex].FindControl("TextBox2");
Response.Write(TB1.ToString());
Response.Write(TB2.ToString());
glj8989332 iT邦研究生 4 級 ‧ 2020-08-24 13:33:44 檢舉

young122333 可以的話, 可以把aspx的宣告打上來, 原先以為只有GridView, 但多了DetailsView, 可能要再試試這種混搭是不是有什麼陷阱.

glj8989332 iT邦研究生 4 級 ‧ 2020-08-24 13:44:45 檢舉

但還是覺得DetailsView不應該有影響, 因為GridView1_RowEditing是被GridView觸發, 要取的Control也是GridView內的元件, 百思不解...另外你Empty "產生的列舉型別沒有結果" string 又是哪裡出錯呢?

阿偉 iT邦新手 2 級 ‧ 2020-08-24 17:28:39 檢舉

因為aspx還參雜很多其他東西
貼上來怕版不夠排

我把語法嘗試寫入RowUpdating
按下送出後,Response.Write確實有抓到TB1.Text 的時間
但是TB1.Text = nowDT.ToString();
時間卻沒真的寫入TextBox1
怪哉

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
  DateTime dt = DateTime.Now;
  string nowDT = dt.ToString("yyyy/MM/dd HH:mm:ss");
  TextBox TB1 = (TextBox)GridView1.Rows[e.RowIndex].FindControl("TextBox1");
  TB1.Text = nowDT.ToString();
  Response.Write(TB1.Text);
  //Response.End();
}

明天我開一個測試頁,只放兩個textbox看看

阿偉 iT邦新手 2 級 ‧ 2020-08-25 13:44:45 檢舉

text2.aspx 只放入兩個欄位,一個是pk,一個是編輯時要自動填入DateTime

GridView1

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="RTR_Num" DataSourceID="SqlDataSource1" OnRowEditing="GridView1_RowEditing">
<Columns>
   <asp:CommandField ShowEditButton="True" />
   <asp:BoundField DataField="RTR_Num" HeaderText="RTR_Num" ReadOnly="True" SortExpression="RTR_Num" />
   <asp:TemplateField HeaderText="Last_Modify" SortExpression="Last_Modify">
       <EditItemTemplate>
          <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Last_Modify") %>'></asp:TextBox>
       </EditItemTemplate>
       <ItemTemplate>
          <asp:Label ID="Label1" runat="server" Text='<%# Bind("Last_Modify") %>'></asp:Label>
       </ItemTemplate>
   </asp:TemplateField>
 </Columns>
</asp:GridView>

SqlDataSource

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:STOCK_MGMTConnectionString %>" DeleteCommand="DELETE FROM [Recd_Trans_Record] WHERE [RTR_Num] = @RTR_Num" InsertCommand="INSERT INTO [Recd_Trans_Record] ([RTR_Num], [Last_Modify]) VALUES (@RTR_Num, @Last_Modify)" SelectCommand="SELECT [RTR_Num], [Last_Modify] FROM [Recd_Trans_Record]" UpdateCommand="UPDATE [Recd_Trans_Record] SET [Last_Modify] = @Last_Modify WHERE [RTR_Num] = @RTR_Num">
   <DeleteParameters>
      <asp:Parameter Name="RTR_Num" Type="String" />
   </DeleteParameters>
   <InsertParameters>
      <asp:Parameter Name="RTR_Num" Type="String" />
      <asp:Parameter Name="Last_Modify" Type="DateTime" />
   </InsertParameters>
    <UpdateParameters>
      <asp:Parameter Name="Last_Modify" Type="DateTime" />
      <asp:Parameter Name="RTR_Num" Type="String" />
    </UpdateParameters>
</asp:SqlDataSource>

CS

protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
   DateTime dt = DateTime.Now;
   string nowDT = dt.ToString("yyyy/MM/dd HH:mm:ss");
   TextBox TB1 = (TextBox)GridView1.Rows[e.NewEditIndex].FindControl("TextBox1");
   TB1.Text = nowDT.ToString();
}

為了方便測試,我只開兩個位置
並且不手動調整程式碼跟SQL
按下編輯按鈕時,一樣會報錯
https://ithelp.ithome.com.tw/upload/images/20200825/20082456XSVS6MzzBa.jpg

glj8989332 iT邦研究生 4 級 ‧ 2020-08-25 16:11:04 檢舉

young122333 我在原文更新了解法, 要用RowDataBound才能抓到~ 還好有問到你的aspx寫法 XD

阿偉 iT邦新手 2 級 ‧ 2020-08-25 17:28:42 檢舉

感謝,可以了!

glj8989332 iT邦研究生 4 級 ‧ 2020-08-25 17:34:04 檢舉

/images/emoticon/emoticon08.gif

0
雞湯工程師
iT邦新手 4 級 ‧ 2020-08-23 14:09:45

如果先試試
TextBox TB1 = new TextBox();
TB1 = (TextBox)GridView1.Rows[e.NewEditIndex].FindControl("TextBox1");
再用TB1去接值呢??

阿偉 iT邦新手 2 級 ‧ 2020-08-24 12:59:12 檢舉

無法
我將語法寫在 GridView1 編輯按鈕 Button1_Click2內

protected void Button1_Click2(object sender, EventArgs e)
{
   DateTime dt = DateTime.Now;
   string toDate = dt.ToString("yyyy-MM-dd");
   string nowTime = dt.ToString("HH:mm:ss");
   GridViewRow gvw = (GridViewRow)((Button)sender).NamingContainer;
   TextBox TB1 = (TextBox)gvw.FindControl("TextBox1");
   TextBox TB1 = (TextBox)gvw.FindControl("TextBox2");
   TB1.Text = toDate;
   TB2.Text = nowTime;
}

結果還是不行

我要發表回答

立即登入回答