我們知道ListView在內容超出控件本身范圍時,默認會把滾動條顯示出來。 這個內容,顯然應該包括Head和Items兩個部分。無論哪個部分超出了,都應該 把水平滾動條顯示出來。
ListView的Bug就在於,當ListView中沒有Item,且Headr的總長超過 ListView本身時,水平滾動條沒有出現。
這個Bug很好重現。代碼如下:
<Grid x:Name="LayoutRoot"> <ListView Width="100"> <ListView.View> <GridView> <GridViewColumn Header="Name"/> <GridViewColumn Header="Value"/> <GridViewColumn Header="Length"/> <GridViewColumn Header="Format"/> <GridViewColumn Header="Error Information"/> </GridView> </ListView.View> </ListView> </Grid>
運行效果如下圖所示:
這可能是我發現過的問題本身最簡單,但是解決起來很復雜的一個Bug了。
問題出在什麼地方呢?仔細分析ListView的XAML Structure,如下圖:
在ListView的Template裡,我們看到ScrollViewer裡沒有HeaderPresenter, 而只有ItemsPresenter。那麼HeaderPresenter在什麼地方呢?沒有錯,就在 ScrollViewer裡。如下圖所示。
問題就出在這裡,放在ScrollViewer的Template裡的HeaderPresenter,並不 屬於需要被Scroll的Content。所以當Header超出范圍時,ScrollViewer的 ScrollBar並不會出現。至於為什麼微軟要把HeaderPresenter放在ScrollViewer 的Template裡?
想想滾動垂直滾動條的時候,是不是只有Items滾動?而Header一直在最上面 ?如果把Header作為Content,那麼Header也會隨著Items一直滾動了。這是一個 比超長Header水平滾動條不出現更大的一個Bug。所以在WPF現有的Control Sets 的約束下,只能這樣子。
但是水平滾動條在沒有Items時不出現,依然是一個Bug。這個Bug的解決辦法 相當復雜,需要有Selective Scrolling的功能(WPF Toolkit有提供)。解決方 案下回講解。(如果我能在自己能接受的時間內實現出來的話……)