[ListView]取得EmptyDataTemplate裡面Control的值
前言
上一次,是耍笨在找不到ListView LayoutTemplate上的control,後來是虛驚一場,可以參考:[Tips]如何找到ListView的LayoutTemplate上的control。
這一次則是member碰到了一個需求,是當ListView沒有資料的時候,要可以讓user操作別的功能,來使得ListView有資料。(也可以想像成新增功能)然而,member在ListView的EmptyDataTemplate中設置的control,卻無法在Item_Created以外的事件,去findcontrol找到EmptyDataTempalte裡面的control。(在這個case裡面,在Item_Created事件去設定EmptyDataTemplate中DropDownList的DataSource)
試了幾種方法,在不同的事件底下,似乎真的都找不到EmptyDataTemplate裡面的control。
最後只有試出一種方式,是使用最土法煉鋼的方式:ListView.Controls[0].FindControl("myDrp"),透過Controls[0]去找到EmptyDataTemplate這一個Item。(實在不是很喜歡這種使用Controls[0]硬抓的方式)
後來也有上去MSDN forum發問,這邊補上該討論串:如何取到ListView的EmptyDataTemplate裡面control的值
簡單範例
//其中的Controls[0]是指'EmptyDataTemplate'是在Listview中的第一個Control
DropDownList obj = listView.Controls[0].FindControl("drpGroupSource") as DropDownList ;
<asp:ListView ID="lvwGroupSource" runat="server" >
<EmptyDataTemplate>
<asp:DropDownList ID="drpGroupSource" runat="server" > </asp:DropDownList>
</EmptyDataTemplate>
<LayoutTemplate>
....
</LayoutTemplate>
</ListView >
後記
值得留意的幾個issue,有一些是常識,不過還是列出來讓沒有頭緒的朋友參考一下:
-
Item_Created的事件不管有沒資料都會跑,但ItemDataBound有資料才會進來這事件。
-
Controls[0]這種方式,之所以我很不喜歡,是因為太容易受到影響,如果中間多插入了一個其他的server control,就可能導致原本可以正常運作的code出現例外。
但,在這個case中,後來琢磨了一下,要出現例外的情況應該是微乎其微。
因為ListView沒資料的時候,會Render出來的,就只有EmptyDataTemplate這個東西,其他的東西都不會出來。
所以,也就是當binding後沒有資料時,只會有一個Control,就是EmptyDataTempalte。雖然Controls[0].FindControl醜了點,不過至少不會有啥例外,可以勉強湊合著用了。
-
最後這個case,並不是使用EmptyDataTemplate的方式解決,而是請她將『ListView沒有資料』的意義再抽象一層出來,自己去定義一個區塊,是當ListView沒有資料時要作的處理,用一般的table套用相同的css,以及一樣的control去作同樣的需求。
而不是將這樣的需求,硬加諸於ListView的EmptyDataTemaplte上,而讓EmptyDataTemaplte變成很單純的只是沒有資料時,要顯示的畫面,不包含UI的操作。可以保留未來維護與修改的彈性,也可以讓畫面更好控制,當ListView沒有資料,要作其他事情可能與ListView無關時,程式碼的抽象等級也會比較一致。
感謝MSDN forum上鼎力相助的前輩們,也感謝我的同事: Beryl,提出這麼好的問題以及記錄下來解法,讓我有機會多學會到了沒碰過的東西。
blog 與課程更新內容,請前往新站位置:http://tdd.best/