如何在ItemsControls中使用AlternationIndex?

时间:2010-08-25 15:48:29

标签: wpf mvvm styles itemscontrol

我看过一些文章,展示如何将AlternationIndexListBox es或ListView s一起使用,但我花了几个小时试图在基础上获取交替的背景颜色{ {1}}课程似乎没什么用。我看到的所有ItemsControl个样本都使用ListBox作为基于ListBoxItem设置背景的样式的目标类型 - 就像来自MSDN的这样:

AlternationIndex

我想使用<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> 因为我不想要选择功能,我认为重新设置ItemsControl来隐藏它可能不是最好的选择。

这是我尝试过的事情之一:

ListBox

我看到的问题是,可视化树有一个<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> 列表,其中ContentPresenter在0和1之间交替,但每个ItemsControl.AlternationIndex中的Grid都有ContentPresenter设为0。

可能有一些显而易见的事我错过了......

5 个答案:

答案 0 :(得分:45)

ItemContainerStyle应用于ItemsControl:ContentPresenter生成的元素。 ContentPresenter将包含您在ItemTemplate中放置的任何内容。对于ListBox,ItemContainerStyle应用于生成的ListBoxItem。

AlternationCount根据您发布的内容,仅适用于这些生成的项目。您不能使用ItemContainerStyle来设置网格的背景,因为该格式不知道网格。

以下是理想的,但不幸的是ContentPresenter没有背景属性。但它适用于ListBox(带有ListBoxItems)。

<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>

因此,您最终会为网格编写一个样式,该样式会绑定到您的父ContentPresenter的AlternationIndex。

<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>

答案 1 :(得分:25)

hm ..玩了大约2个小时后,我终于找到了简单有效的解决方案:

       <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>

我希望这个答案能帮助他人节省一些时间。

答案 2 :(得分:2)

或者,正如我在另一篇文章中发现的那样,它对我很有用...... 你可以简单地使用绑定......

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

注意:记得添加AlterationCount =&#34; 100&#34;在您的ItemsControl上

答案 3 :(得分:0)

如果您不想使用DataTemplate方法,则可以创建使用ContentControl作为项容器的自定义控件,从而允许您指定背景颜色。

类别:

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;
    }
}

资源词典:

<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>

答案 4 :(得分:0)

我不知道任何先前的答案是否合法。我不能让他们中的任何一个工作(虽然没有尝试雅各比)。无论如何,我在这里找到了启示之路:http://www.dotnetcurry.com/wpf/1211/wpf-items-control-advanced-topic,它引导我在xaml.cs代码隐藏中添加以下内容:

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

这是在xaml本身

    <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>

这真是太难找到一个有效的解决方案,我真的生气了