天天看點

WPF集合控件實作分隔符(ItemsControl Separator)

在WPF的集合控件中常常需要在每一個集合項之間插入一個分隔符樣式,但是WPF的ItemsControl沒有相關功能的直接實作,是以隻能考慮曲線救國,經過研究,大概想到了以下兩種實作方式。

先寫出ItemsControl的資料模闆,如下:

<ItemsControl ItemsSource=

"{Binding Source}"

BorderThickness=

"1"

BorderBrush=

"Blue"

VerticalAlignment=

"Stretch"

>

<ItemsControl.ItemTemplate>

<DataTemplate>

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height=

"Auto"

/>

<RowDefinition Height=

"*"

/>

</Grid.RowDefinitions>

<Border Name=

"Bd"

Grid.Row=

"0"

Height=

"1"

Background=

"Red"

/>

<TextBlock Grid.Row=

"1"

Text=

"{Binding}"

/>

</Grid>

</DataTemplate>

</ItemsControl.ItemTemplate>

</ItemsControl>

其中名為Bd的Border就是分隔符,此時每一項的頭部都可以看見分隔符,現在我們的目标是要隐藏掉第一項的分隔符,這就達到了項與項之間才有分隔符的目的。

第一種實作方式最簡單,使用集合項前向綁定PreviousData,這是四種綁定方式中的一種,估計也是平時用得最少的一種,不過此時就派上用場了,代碼如下:

1

2

3

4

5

6

<DataTemplate.Triggers>

<DataTrigger Binding=

"{Binding RelativeSource={RelativeSource PreviousData}}"

Value=

"{x:Null}"

>

<Setter TargetName=

"Bd"

Property=

"Visibility"

Value=

"Collapsed"

/>

</DataTrigger>

</DataTemplate.Triggers>

當某一項的前項為空時就隐藏分隔符,簡單的一行代碼搞定。不過這種實作方式有個缺點就是如果使用的是Insert方式向綁定的資料源的最前面添加資料則就會出現不止一個沒有分隔符的項,如果是往隊尾或者隊中添加則不會出現這個問題。

第二種實作方式是借助ItemsControl的AlternationCount和AlternationIndex屬性來為集合項标記索引号,再隐藏索引号為0的項的分隔符,代碼如下:

複制代碼代碼如下:

<ItemsControl ItemsSource="{Binding Source}" BorderThickness="1" BorderBrush="Blue"

              VerticalAlignment="Stretch" AlternationCount="{Binding Source.Count}">

首先在ItemsControl上綁定AlternationCount到資料源的Count屬性上,然後此時ItemsControl的AlternationIndex屬性就變成的該集合資料源的索引号了,在觸發器中寫上邏輯即可:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<Border Name=

"Bd"

Grid.Row=

"0"

Height=

"1"

Background=

"Red"

>

<Border.Style>

<Style TargetType=

"{x:Type Border}"

>

<Style.Triggers>

<DataTrigger

Binding="{Binding Path=(ItemsControl.AlternationIndex),

RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"

Value=

"0"

>

<Setter Property=

"Visibility"

Value=

"Collapsed"

/>

</DataTrigger>

</Style.Triggers>

</Style>

</Border.Style>

</Border>

觸發器判定當索引号為0時就隐藏Border,這種方式代碼量也不大,優點是能絕對實作這個功能,無論向隊首插入還是隊尾插入,但是AlternationCount和AlternationIndex屬性本來的含義是用來實作比如隔行變色等功能,此時這種功能被占用,是以如果你的集合要同時實作分隔符和隔行樣式的功能可能需要額外加轉換器,不過轉換器内容也很簡單,求個餘數就能還原之前的功能了。