承接上一篇【如何透過JavaScript來觸發LinkButton的PostBack,呼叫後端的程式】,這一篇就利用那個技巧,來實現在GridView中,點選Row的任一位置,就可以選擇該Row。
緣起
承接上一篇【如何透過JavaScript來觸發LinkButton的PostBack,呼叫後端的程式】,這一篇就利用那個技巧,來實現在GridView中,點選Row的任一位置,就可以選擇該Row。
範例:北風的Employees與Orders
我們利用北風資料庫中的Employees與Orders這兩個資料表,來當作我們的範例,透過兩個GridView,第一個GridView顯示所有的Empolyees資料,而點選其中的一個Employee,就在第二個GridView顯示該Employee所有的訂單,這部分透過拖拉放的方式,不用寫任何程式即可達成。(拖拉放的過程,類似這一篇的錄影教學:GridView展現Master-Detail的幾種方式(包含動態錄影教學))而我們先在第一個GridView(Employees)裡面,安排一個TempleteField,然後裡面安排一個LinkButton,並且設定該LinkButton的CommandName為Select。
DataKeyNames="EmployeeID" DataSourceID="SqlDataSource1"
EmptyDataText="沒有資料錄可顯示。">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Select">選擇</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" ReadOnly="True"
SortExpression="EmployeeID" />
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName"
SortExpression="FirstName" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString1 %>"
ProviderName="<%$ ConnectionStrings:NorthwindConnectionString1.ProviderName %>"
SelectCommand="SELECT [EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country], [HomePhone], [Extension], [Photo], [Notes], [ReportsTo], [PhotoPath] FROM [Employees]" >
</asp:SqlDataSource>
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataKeyNames="OrderID" DataSourceID="SqlDataSource2" EmptyDataText="沒有資料錄可顯示。">
<Columns>
<asp:BoundField DataField="OrderID" HeaderText="OrderID" InsertVisible="False"
ReadOnly="True" SortExpression="OrderID" />
<asp:BoundField DataField="CustomerID" HeaderText="CustomerID"
SortExpression="CustomerID" />
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID"
SortExpression="EmployeeID" />
<asp:BoundField DataField="OrderDate" HeaderText="OrderDate"
SortExpression="OrderDate" />
<asp:BoundField DataField="RequiredDate" HeaderText="RequiredDate"
SortExpression="RequiredDate" />
<asp:BoundField DataField="ShippedDate" HeaderText="ShippedDate"
SortExpression="ShippedDate" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString1 %>"
ProviderName="<%$ ConnectionStrings:NorthwindConnectionString1.ProviderName %>"
SelectCommand="SELECT [OrderID], [CustomerID], [EmployeeID], [OrderDate], [RequiredDate], [ShippedDate] FROM [Orders] WHERE ([EmployeeID] = @EmployeeID)" >
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" Name="EmployeeID"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
觀察HTML原始碼
以上的操作過程並不特別困難。然後我們去觀察一下他在瀏覽器上的HTML與JavaScript的原始碼
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
<a id="GridView1_ctl02_LinkButton1" href="javascript:__doPostBack('GridView1$ctl02$LinkButton1','')">選擇</a>
</td><td>1</td><td>Davolio</td><td>Nancy</td>
</tr><tr>
<td>
<a id="GridView1_ctl03_LinkButton1" href="javascript:__doPostBack('GridView1$ctl03$LinkButton1','')">選擇</a>
</td><td>2</td><td>Fuller</td><td>Andrew</td>
</tr><tr>
<td>
<a id="GridView1_ctl04_LinkButton1" href="javascript:__doPostBack('GridView1$ctl04$LinkButton1','')">選擇</a>
</td><td>3</td><td>Leverling</td><td>Janet</td>
</tr><tr>
<td>
<a id="GridView1_ctl05_LinkButton1" href="javascript:__doPostBack('GridView1$ctl05$LinkButton1','')">選擇</a>
</td><td>4</td><td>Peacock</td><td>Margaret</td>
</tr><tr>
<td>
可以觀察到
- GridView產生的HTML是一個<table></table>
- LinkButton所產生的<a>透過呼叫【javascript:__doPostBack('GridView1$ctl02$LinkButton1','')】來觸發PostBack產生Select的動作,並且觸發後端的RowSelecting,RowSelected等事件。
- JavaScript所傳遞的參數,剛好就是該<a>的id,也就是該LinkButton的ClientId,不過不同的是,ClientID用底線【_】,在參數中確是用【$】
有了以上的觀察,我們就可以利用這樣個結果,如果我們讓GridView的每一個Row(Client端是<Tr>)可以有個JavaScript的【Click事件】,並且做LinkButton一樣的事情,這樣就可以讓該Row的任一位置都有選擇的功能了。
RowDataBound加上JavaScript控制
有了以上的觀察,我們就可以在GridView1的RowDataBound的事件中,加上需要的JavaScript控制。
(這部分有修正,保留原來的方式,正確的方式請參考本篇最下方!!)
'判斷資料列才做事情
If e.Row.RowType = DataControlRowType.DataRow Then
'取得LinkButton物件
Dim lb As LinkButton = e.Row.Cells(0).FindControl("LinkButton1")
'判斷有取得物件,才做是情
If lb IsNot Nothing Then
'取得LinkButton的ClientID
Dim lbClientId As String = lb.ClientID
'將底線【_】置換為【$】
lbClientId = Replace(lbClientId, "_", "$")
'設定要加上的JavaScript
Dim tScript As String = ""
tScript = "__doPostBack('" + lbClientId + "','')"
'把JavaScript加在Row的【onclick】屬性裡面
e.Row.Attributes.Add("onclick", tScript)
'增加變換手指游標,以及背景顏色
e.Row.Attributes.Add("onmouseover", "this.style.cursor='hand';this.style.backgroundColor='yellow';")
e.Row.Attributes.Add("onmouseout", "this.style.cursor='';this.style.backgroundColor='';")
End If
End If
End Sub
讓【選擇】消失
運作看看,果然是可以了。不過,還有個問題,如果想要讓LinkButton那個【選擇】的字不見,怎麼做??這個當然不能把LinkButton刪除掉,因為我們主要還是透過LinkButton來達到這樣的效果,方式很簡單,讓LinkButton的【選擇】變成空白即可。
那麼如果連那個欄位(看起來空的TempleteField)也不要呢,也可以,首先要挑選其中一個欄位轉為TempleteField,例如我選擇EmployeeID,然後把剛剛的LinkButton剪下→貼上到EmployeeID裡面的ItemTemplete就可以囉
DataKeyNames="EmployeeID" DataSourceID="SqlDataSource1"
EmptyDataText="沒有資料錄可顯示。">
<Columns>
<asp:TemplateField HeaderText="EmployeeID" SortExpression="EmployeeID">
<EditItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("EmployeeID") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("EmployeeID") %>'></asp:Label>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Select"> </asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName"
SortExpression="FirstName" />
</Columns>
</asp:GridView>
這樣的技巧,其實可以運用在很多地方,讓我們的程式可以設計的更靈活些。提供大家參考
後記補充:
感謝TerryChen大大的指導,提出不同的做法,小喵研究了一下。如果將GridView不使用Templete,但是務必勾選【樞紐分析選取模式】,此時會在GridView裡面多了一個CommandField,裡面會有選取的命令。如果以後不想看到這個選取,可以設定他為不顯示。所以GridView的內容如下:
DataKeyNames="EmployeeID" DataSourceID="SqlDataSource1"
EmptyDataText="沒有資料錄可顯示。">
<Columns>
<asp:CommandField ShowSelectButton="True" Visible="False" />
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" ReadOnly="True"
SortExpression="EmployeeID" />
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName"
SortExpression="FirstName" />
</Columns>
</asp:GridView>
這時候在GridView的RowDataBound事件中,加入如下
If e.Row.RowType = DataControlRowType.DataRow Then
Dim tScript As String = ""
'透過GetPostBackClientHyperlink產生PostBack的JavaScript
tScript = ClientScript.GetPostBackClientHyperlink(Me.GridView1, "Select$" + e.Row.RowIndex.ToString())
'加入PostBack的JavaScript
e.Row.Attributes.Add("onclick", tScript)
'設定游標為手
e.Row.Style("cursor") = "hand"
'增加變換背景顏色
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='yellow';")
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='';")
End If
End Sub
這樣就可以獲得一樣的效果。這邊發現,主要是透過內建的CommandField,他其實也是類似LinkButton的模式,產生PostBack的語法。而透過這樣的練習讓小喵發覺,正確的去產生PostBack的JavaScript,應該要透過【ClientScript.GetPostBackHyperlink】來產生比較恰當。
因此,小喵的程式,也修正了一下,讓ClientScript.GetPostBackHyperlink來產生Script,而不是強制的產生…修改結果如下:
'判斷資料列才做事情
If e.Row.RowType = DataControlRowType.DataRow Then
'取得LinkButton物件
Dim lb As LinkButton = e.Row.Cells(0).FindControl("LinkButton1")
'判斷有取得物件,才做是情
If lb IsNot Nothing Then
'設定要加上的JavaScript
Dim tScript As String = ""
tScript = Page.ClientScript.GetPostBackClientHyperlink(lb, "")
'把JavaScript加在Row的【onclick】屬性裡面
e.Row.Attributes.Add("onclick", tScript)
'增加變換手指游標,以及背景顏色
e.Row.Attributes.Add("onmouseover", "this.style.cursor='hand';this.style.backgroundColor='yellow';")
e.Row.Attributes.Add("onmouseout", "this.style.cursor='';this.style.backgroundColor='';")
End If
End If
End Sub
以下是簽名:
- 歡迎轉貼本站的文章,不過請在貼文主旨上加上【轉貼】,並在文章中附上本篇的超連結與站名【topcat姍舞之間的極度凝聚】,感恩大家的配合。
- 小喵大部分的文章會以小喵熟悉的語言VB.NET撰寫,如果您需要C#的Code,也許您可以試著用線上的工具進行轉換,這裡提供幾個參考
Microsoft MVP Visual Studio and Development Technologies (2005~2019/6) | topcat Blog:http://www.dotblogs.com.tw/topcat |