WPF 改變 ListBox 的 Panel

改變 ListBox 的 Panel 讓他看起來很不一樣

知道 ListBox 的架構後(WPF ListBox 的結構)

我們來試試看改變 ListBox 的各種 Template 來做些有趣的應用。

首先拉出一個 ListBox,並且隨便建立一些資料

<ListBox >
    <TextBlock Text="Object1"/>
    <TextBlock Text="Object2"/>
    <TextBlock Text="Object3"/>
</ListBox>

畫面看起來如下

接著建立 ItemsPanel 

然後把產生出來的 ItemsPanelTemplate 改成用 Canvas,如下

<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
    <Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>

此時畫面會變成

這是因為放資料的容器變成 Canvas ,是一個可以用絕對定位的容器,

接著我們來試試看改變他的座標位置,

試著在資料裡加上 Canvas.Left 和 Canvas.Top

<ListBox ItemsPanel="{DynamicResource ItemsPanelTemplate1}" >
    <TextBlock Text="Object1" Canvas.Left="100" Canvas.Top="100"/>
    <TextBlock Text="Object2" Canvas.Left="200" Canvas.Top="100"/>
    <TextBlock Text="Object3" Canvas.Left="100" Canvas.Top="200"/>
</ListBox>

會發現畫面並沒有改變,這是因為 ListBox 的資料其實都會放到 ListBoxItem 裡,

所以實際上 Canvas 裡面的控制項並不直接就是 TextBlock,而是 ListBoxItem。

所以我們要另外設定 ItemContainerStyle

修改建立後的 Style, 加上這兩行

<Setter Property="Canvas.Left" Value="{Binding (Canvas.Left)}"/>
<Setter Property="Canvas.Top" Value="{Binding (Canvas.Top)}"/>

表示 ListBoxItem 的 Canvas.Lift 屬性繫結到其內部資料的 Canvas.Left 屬性上, Canvas.Top 也是一樣。

就可以看到畫面上出現的改變

裡面的資料就會根據 Canvas.Top 和 Canvas.Left 屬性而做絕對定位的顯示了。