2014年1月14日 星期二

[ASP.NET]GridView的行轉成template跟沒轉template抓取控制項的差別


今天晚上遇到一個Bug

我在GridView裡面的RowUpdating撰寫當你觸發編輯時的程式流程

TextBox TextBox_Name, TextBox_Price, TextBox_Intro;
TextBox_Name = GridView1.Rows[e.RowIndex].Cells[3].Controls[0] as TextBox;
TextBox_Price = GridView1.Rows[e.RowIndex].Cells[4].Controls[0] as TextBox;
TextBox_Intro = GridView1.Rows[e.RowIndex].Cells[5].Controls[0] as TextBox;

編輯時會先抓GridView第4、5、6行的控制項轉型成TextBox

可是奇怪的是這樣寫後面程式會出現TextBox_Name的值是null的錯誤

TextBox_Name = (TextBox)GridView1.Rows[e.RowIndex].Cells[3].Controls[0];

這樣寫又會出現Unable to cast object of type 'System.Web.UI.LiteralControl' to type 'System.Web.UI.WebControls.TextBox'.轉型失敗的錯誤

結果這個問題搞了一整晚

最後程式重寫一遍-正常

但我發現當我把某行轉成Template時相同的錯誤又出現了

這下就確定是因為Template造成的錯誤

後來突然想到用FindControl()來抓看看

TextBox TextBox_Name, TextBox_Price, TextBox_Intro;
TextBox_Name = GridView1.Rows[e.RowIndex].FindControl("TextBox1") as TextBox;
TextBox_Price = GridView1.Rows[e.RowIndex].Cells[4].Controls[0] as TextBox;
TextBox_Intro = GridView1.Rows[e.RowIndex].FindControl("TextBox2") as TextBox;

改成這樣就對了

原因是當你GridView的行轉成Template(樣板)之後

你必須要用GridView1.Rows[e.RowIndex].FindControl("TextBox1")這個方式才能抓到該行的控制項

像是TextBox_Price因為沒有轉成樣板

所以用GridView1.Rows[e.RowIndex].Cells[4].Controls[0] as TextBox這種方法就能夠抓到

在FindControl()跟Cell的使用區別還不夠熟練阿~