我在 超完美組合:LinqDataSource + ListView + DataPager + jQuery 文章中有概略提到如何透過一個 LinqDataSource 控制項進行「雙層 ListView 控制項」的套版,不過我最近卻遇到一個問題,也就是「第二層」的 ListView 顯示的資料無法指定特定欄位做排序(Sorting)。
我曾經嘗試用 ListView2.Sort("Sort", ....) 這種方式在 ListView2 的地方進行手動的排序動作,不過卻會導致 DataSource='<%#Eval("ProductCategory_Child") %>' 這個部分出錯,錯誤訊息如下:
Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control
而我所想到的解決方法有二:
1. 在第一層 ListView 中額外宣告一個 LinqDataSource 控制項與 HiddenField 控制項,進行第二層資料的宣告,並指定排序。
<asp:HiddenField runat="server" ID="hf_ProductCategoryID"
Visible="false" Value='<%# Eval("ID") %>' />
<asp:LinqDataSource ID="ldsProduct" runat="server"
ContextTypeName="MyDataContext" TableName="Product"
Select="new(ID,Name)"
Where="ProductCategoryID == Guid(@ProductCategoryID)"
OrderBy="Sort">
<WhereParameters>
<asp:ControlParameter ControlID="hf_ProductCategoryID"
Name="ProductCategoryID" Type="Object" />
</WhereParameters>
</asp:LinqDataSource>
2. 第二層 ListView 改用一個 UserControl 包起來,將排序的邏輯與資料的查詢都封裝在一個 UserControl 裡面,原本的頁面只要將 ID 欄位值傳入 UserControl 即可。(ListView的內容也必須寫到)
<%@ Control Language="C#" AutoEventWireup="true" %>
<script runat="server"> 1:
2: [System.ComponentModel.Bindable(true)]
3: public Guid ProductCategoryID
4: {
5: get
6: {
7: return new Guid(hf_ProductCategoryID.Value);
8: }
9: set
10: {
11: hf_ProductCategoryID.Value = value.ToString();
12: }
13: }
14:
15: protected void Page_Load(object sender, EventArgs e)
16: {
17:
18: }
</script>
<asp:HiddenField runat="server" ID="hf_ProductCategoryID"
Visible="false" Value='<%# Eval("ID") %>' />
<asp:LinqDataSource ID="ldsProduct" runat="server"
ContextTypeName="MyDataContext"
Select="new(ID,Name)"
TableName="Product"
Where="ProductCategoryID == Guid(@ProductCategoryID)"
OrderBy="Sort">
<WhereParameters>
<asp:ControlParameter ControlID="hf_ProductCategoryID"
Name="ProductCategoryID" Type="Object" />
</WhereParameters>
</asp:LinqDataSource>