2010-08-25 19 views
22

ListBox es ya da ListView s ile AlternationIndex'un nasıl kullanılacağını gösteren bazı makaleler gördüm, ancak ItemsControl sınıfında alternatif arka plan renkleri almaya çalışırken birkaç saat harcadım ve hiçbir şey işe yaramıyor gibi görünüyor.ItemsControls içinde AlternationIndex nasıl kullanılır?

<Grid> 
    <Grid.Resources> 
     <Style x:Key="alternatingWithTriggers" TargetType="{x:Type ListBoxItem}"> 
      <Setter Property="Background" Value="Blue"/> 
      <Setter Property="Foreground" Value="White"/> 
      <Style.Triggers> 
       <Trigger Property="ListBox.AlternationIndex" Value="1"> 
        <Setter Property="Background" Value="CornflowerBlue"/> 
        <Setter Property="Foreground" Value="Black"/> 
       </Trigger> 
       <Trigger Property="ListBox.AlternationIndex" Value="2"> 
        <Setter Property="Background" Value="LightBlue"/> 
        <Setter Property="Foreground" Value="Navy"/> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 

    </Grid.Resources> 
    <ListBox AlternationCount="3" ItemsSource="{StaticResource data}" 
      ItemContainerStyle="{StaticResource alternatingWithTriggers}"> 
    </ListBox> 
</Grid> 

Ben seçim işlevselliği istemiyorum çünkü ItemsControl kullanmak istiyorsanız ve: bu MSDN gelen biri gibi - Bütün ListBox numuneler ben AlternationIndex dayalı arka ayarlar bu stil için hedef türü olarak ListBoxItem kullanırken gördüğünü Saklamak için ListBox'u tekrar kullanmak en iyi seçim olmayabilir.

Bu şeylerin Deniyordum biridir:

<DataTemplate DataType="{x:Type vm:ObservableCollectionItem}"> 
    <Grid> 
     <!-- some content here --> 
    </Grid> 
</DataTemplate> 

<!-- ... --> 

<ItemsControl 
    ItemsSource="{Binding ObservableCollectionItems}" 
    AlternationCount="2" 
> 
    <ItemsControl.ItemContainerStyle> 
     <Style> 
      <Style.Triggers> 
       <Trigger Property="ItemsControl.AlternationIndex" Value="0"> 
        <Setter Property="Grid.Background" Value="Red"></Setter> 
       </Trigger> 
       <Trigger Property="ItemsControl.AlternationIndex" Value="1"> 
        <Setter Property="Grid.Background" Value="Blue"></Setter> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
</ItemsControl> 

Görsel ağaç 0 ile 1 arasında ItemsControl.AlternationIndex alternatif var ContentPresenter s listesini sahip olduğunu gördüm bir sorun, ama her GridContentPresenterItemsControl.AlternationIndex

cevap

38

ItemContainerStyle tarafından oluşturulan elemanlarına uygulandığı ... 0'a

ben eksik belirgin bir şey muhtemelen yoktur ayarlamıştır ItemsControl: ContentPresenter. ContentPresenter, sırasıyla ItemTemplate ürününe koyduğunuz her şeyi içerir. ListBox durumunda, ItemContainerStyle oluşturulan ListBoxItem uygulanır.

AlternationCount, yayınladığınız öğelere dayanarak yalnızca bu oluşturulan öğelerde kullanılabilir. Grid'in arka planını ayarlamak için ItemContainerStyle'ı kullanamazsınız, çünkü Grid bu Stilde bilinmemektedir.

Aşağıdakiler ideal olacaktır, ancak ne yazık ki ContentPresenter'ın arka plan özelliği yoktur. Ancak bir ListBox (ListBoxItems ile) için çalışır.

<ItemsControl 
    ItemsSource="{Binding ObservableCollectionItems}" 
    AlternationCount="2"> 
    <ItemsControl.ItemContainerStyle> 
     <Style TargetType="ContentPresenter"> 
      <Style.Triggers> 
       <Trigger Property="ItemsControl.AlternationIndex" Value="0"> 
        <Setter Property="Background" Value="Red"></Setter> 
       </Trigger> 
       <Trigger Property="ItemsControl.AlternationIndex" Value="1"> 
        <Setter Property="Background" Value="Blue"></Setter> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
</ItemsControl> 

Yani ebeveyn ContentPresenter ait AlternationIndex bağlanan ızgara için bir stil yazma sonunda.

 <ItemsControl ItemsSource="{Binding}" AlternationCount="2"> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <Grid Background="Transparent" x:Name="__PART_GRID"></Grid> 
         <DataTemplate.Triggers> 
          <Trigger Property="ItemsControl.AlternationIndex" Value="0"> 
           <Setter TargetName="__PART_GRID" Property="Background" Value="Red"/> 
          </Trigger> 
          <Trigger Property="ItemsControl.AlternationIndex" Value="1"> 
           <Setter TargetName="__PART_GRID" Property="Background" Value="Blue"/> 
          </Trigger> 
         </DataTemplate.Triggers> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
     </ItemsControl> 

Bu cevap biraz zaman kazanmak için başkalarına yardımcı olur umarım:

<DataTemplate DataType="{x:Type vm:ObservableCollectionItem}"> 
    <Grid> 
     <Grid.Style> 
      <Style TargetType="Grid"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="0"> 
         <Setter Property="Background" Value="Red"/> 
        </DataTrigger> 
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="1"> 
         <Setter Property="Background" Value="Blue"/> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </Grid.Style> 
    </Grid> 
</DataTemplate> 
+0

ürününüze AlterationCount = "100" eklemeyi unutmayın. Teşekkürler! Bu arama bağlantısının büyük ItemControls üzerinde ölçeklenip ölçeklenmeyeceğini merak ediyorum ama neyse ki benim durumum bu değil. –

+1

İkinci örnek, ContentPresenter'ın * özelliği * bir 'Arkaplan 'özelliğine sahip olmadığından, işe yaramaz. – Will

+8

Örnekten hemen önce söylediğim gibi;) – Bubblewrap

24

hm .. Yaklaşık 2 saat uğraşırken sonra nihayet basitçe çalışır çözüm buldu.

+0

Bu çözüm, @Bubblewrap tarafından önerilenden çok daha ** daha nettir ... +1! Teşekkürler! – AxelEckenberger

+0

Kesinlikle daha temiz bir çözüm, IMO. Dikkat çekici olabilir, adlandırılan bileşen tetikleyicilerin önüne gelmelidir veya bir hata verir. (Ancak, sorunun ne olduğu konusunda hata mesajı oldukça açık) – Herohtar

0

DataTemplate yaklaşımını kullanmak istemiyorsanız, öğe konteyneri olarak ContentControl kullanan özel bir denetim oluşturabilir ve bu nedenle arka plan rengi belirtmenize izin verebilirsiniz.

Sınıf:

public class ItemsControlAlternating : ItemsControl 
{ 
    static ItemsControlAlternating() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(ItemsControlAlternating), 
       new FrameworkPropertyMetadata(typeof(ItemsControlAlternating))); 
    } 

    protected override DependencyObject GetContainerForItemOverride() 
    { 
     return new ContentControl(); 
    } 

    protected override bool IsItemItsOwnContainerOverride(object item) 
    { 
     return item is ContentControl; 
    } 
} 

Kaynak Sözlük: Ben önceki cevapların hiçbirinde okunaklı bilmiyorum

<Style TargetType="{x:Type c:ItemsControlAlternating}"> 
    <Setter Property="AlternationCount" Value="2"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type c:ItemsControlAlternating}"> 
       <ItemsPresenter/> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="ItemContainerStyle"> 
     <Setter.Value> 
      <Style TargetType="{x:Type ContentControl}"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type ContentControl}"> 
          <Border Background="{TemplateBinding Background}"> 
           <ContentPresenter/> 
          </Border> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
       <Style.Triggers> 
        <Trigger Property="ItemsControl.AlternationIndex" Value="0"> 
         <Setter Property="Background" Value="Gray"/> 
        </Trigger> 
        <Trigger Property="ItemsControl.AlternationIndex" Value="1"> 
         <Setter Property="Background" Value="White"/> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </Setter.Value> 
    </Setter> 
</Style> 
0

. Onların hiçbirini işe yaratamadım (Jacobi'yi denemedim). Her neyse, burada aydınlanma yolunu buldum: http://www.dotnetcurry.com/wpf/1211/wpf-items-control-advanced-topic, bu da beni xaml'de eklemeye yönlendirdi.cs arkasında kod: xaml kendisi

<local:CustomItemsControl AlternationCount="2" 
      ItemsSource="{Binding Cells, Mode=OneWay}"> 
     <local:CustomItemsControl.ItemContainerStyle> 
      <Style TargetType="ContentControl"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="ContentControl"> 
          <Border Background="{TemplateBinding Background}"> 
           <ContentPresenter/> 
          </Border> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 

       <Style.Triggers> 
        <Trigger Property="ItemsControl.AlternationIndex" Value="0"> 
         <Setter Property="Background" Value="WhiteSmoke"/> 
        </Trigger> 
        <Trigger Property="ItemsControl.AlternationIndex" Value="1"> 
         <Setter Property="Background" Value="LightGray"/> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </local:CustomItemsControl.ItemContainerStyle> 
    </local:CustomItemsControl> 

yılında

public sealed class CustomItemsControl : ItemsControl 
{ 
    protected override DependencyObject GetContainerForItemOverride() 
    { 
     return new ContentControl(); 
    } 
} 

ve bu Bu benim I olarak

1

Veya, aslında kızgın olduğumu bir çalışma çözüm bulmak için bu çok zor oldu ... başka bir yazı bulunan ve sadece bir bağlayıcı kullanabilirsiniz ... benim için büyük işler

{Binding 
    RelativeSource={RelativeSource Mode=TemplatedParent}, 
    Path=(ItemsControl.AlternationIndex)} 

NB: ItemsControl

İlgili konular