2011-10-20 76 views
8

我需要對列表視圖的第一項和最後一項進行不同的樣式設置。爲了達到這個目的,我開始根據這個答案開發一個解決方案:Use different template for last item in a WPF itemscontrolListView中第一項和最後一項的不同項目模板

基本上,我有一個自定義的ItemsTemplateSelector,根據列表視圖項目(代碼如下)中的項目索引決定要應用的模板。

它工作正常,除了當列表得到更新(一個項目添加或刪除),模板不會再次被選中(例如,最初,SingleItemTemplate被選中,因爲有一個單一的項目。一個項目到列表中,第一個項目的模板不會切換到FirstItemTemplate)。如何強制所有項目的模板選擇?

public class FirstLastTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate DefaultTemplate { get; set; } 
    public DataTemplate FirstItemTemplate { get; set; } 
    public DataTemplate LastItemTemplate { get; set; } 
    public DataTemplate SingleItemTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     ListView lv = VisualTreeHelperEx.FindParentOfType<ListView>(container); 
     if (lv != null) 
     { 
      if (lv.Items.Count == 1) 
      { 
       return SingleItemTemplate; 
      } 

      int i = lv.Items.IndexOf(item); 
      if (i == 0) 
      { 
       return FirstItemTemplate; 
      } 
      else if (i == lv.Items.Count - 1) 
      { 
       return LastItemTemplate; 
      } 
     } 
     return DefaultTemplate; 
    } 
} 

回答

14

作爲一個替代方法,我建議結合的AlternationCountItemsControl項的在您的收藏數量(例如在Count屬性)。然後這將分配給您的ItemsControl中的每個容器一個唯一的AlternationIndex(0,1,2,... Count-1)。在這裏看到更多的信息:

http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.alternationcount.aspx

一旦每個容器都有一個唯一的AlternationIndex可以使用DataTrigger在你的容器Style設置基於關閉索引的ItemTemplate。這可以通過MultiBinding與轉換器完成,該轉換器在索引等於計數時返回True,否則返回False。當然你也可以圍繞這種方法構建一個選擇器。除了轉換器之外,這種方法非常好,因爲它只是一個XAML解決方案。使用

一個例子的ListBox

<Window x:Class="WpfApplication4.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib" 
     xmlns:System="clr-namespace:System;assembly=mscorlib" 
     xmlns:l="clr-namespace:WpfApplication4" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.Resources> 
      <Collections:ArrayList x:Key="MyCollection"> 
       <System:String>Item One</System:String> 
       <System:String>Item Two</System:String> 
       <System:String>Item Three</System:String> 
      </Collections:ArrayList> 

      <l:MyAlternationEqualityConverter x:Key="MyAlternationEqualityConverter" /> 

      <Style x:Key="MyListBoxItemStyle" TargetType="{x:Type ListBoxItem}"> 
       <Style.Triggers> 
        <DataTrigger Value="True"> 
         <DataTrigger.Binding> 
          <MultiBinding Converter="{StaticResource MyAlternationEqualityConverter}"> 
           <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListBox}}" Path="Items.Count" /> 
           <Binding RelativeSource="{RelativeSource Self}" Path="(ItemsControl.AlternationIndex)" /> 
          </MultiBinding> 
         </DataTrigger.Binding> 
         <!-- Could set the ItemTemplate instead --> 
         <Setter Property="Background" Value="Red"/> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </Grid.Resources> 

     <ListBox ItemsSource="{Binding Source={StaticResource MyCollection}}" 
       AlternationCount="{Binding RelativeSource={RelativeSource Self}, Path=Items.Count}" 
       ItemContainerStyle="{StaticResource MyListBoxItemStyle}" /> 
    </Grid> 

當轉換器可能看起來像:

class MyAlternationEqualityConverter : IMultiValueConverter 
{ 
    #region Implementation of IMultiValueConverter 

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (values != null && values.Length == 2 && 
      values[0] is int && values[1] is int) 
     { 
      return Equals((int) values[0], (int) values[1] + 1); 
     } 

     return DependencyProperty.UnsetValue; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 

    #endregion 
} 
+0

我很奇怪,爲什麼你還沒有使用Datatrigger的綁定到ItemsCount比較,值交替計數?是否因爲ItemCount不是一個依賴項屬性,它會拋出錯誤?還是有其他原因嗎?因爲我看到它將成爲一個等於比較的布爾值,爲什麼我們需要一個轉換器 – CarbineCoder

+0

@ ramb00我試了一下,得到:「A'綁定'不能在類型'DataTrigger'的'Value'屬性上設置」 。看起來值不是一個依賴項。 –

相關問題