[ListView]取得EmptyDataTemplate裡面Control的值

  • 10400
  • 0

[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,有一些是常識,不過還是列出來讓沒有頭緒的朋友參考一下:

  1. Item_Created的事件不管有沒資料都會跑,但ItemDataBound有資料才會進來這事件。
     
  2. Controls[0]這種方式,之所以我很不喜歡,是因為太容易受到影響,如果中間多插入了一個其他的server control,就可能導致原本可以正常運作的code出現例外。

    但,在這個case中,後來琢磨了一下,要出現例外的情況應該是微乎其微。
    因為ListView沒資料的時候,會Render出來的,就只有EmptyDataTemplate這個東西,其他的東西都不會出來。
    所以,也就是當binding後沒有資料時,只會有一個Control,就是EmptyDataTempalte。雖然Controls[0].FindControl醜了點,不過至少不會有啥例外,可以勉強湊合著用了。

     
  3. 最後這個case,並不是使用EmptyDataTemplate的方式解決,而是請她將『ListView沒有資料』的意義再抽象一層出來,自己去定義一個區塊,是當ListView沒有資料時要作的處理,用一般的table套用相同的css,以及一樣的control去作同樣的需求。
    而不是將這樣的需求,硬加諸於ListView的EmptyDataTemaplte上,而讓EmptyDataTemaplte變成很單純的只是沒有資料時,要顯示的畫面,不包含UI的操作。可以保留未來維護與修改的彈性,也可以讓畫面更好控制,當ListView沒有資料,要作其他事情可能與ListView無關時,程式碼的抽象等級也會比較一致。


感謝MSDN forum上鼎力相助的前輩們,也感謝我的同事: Beryl,提出這麼好的問題以及記錄下來解法,讓我有機會多學會到了沒碰過的東西。


blog 與課程更新內容,請前往新站位置:http://tdd.best/