wpf 如何在 ItemsControls 中使用 AlternationIndex?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3567778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use AlternationIndex in ItemsControls?
提问by Filip Skakun
I have seen some articles that show how to use AlternationIndex
with ListBox
es or ListView
s, but I had spent a few hours trying to get alternating background colors on the base ItemsControl
class and nothing seems to work. All ListBox
samples I saw use ListBoxItem
as the target type for the style that sets the background based onAlternationIndex
- like this one from MSDN:
我已经看到一些文章,展示了如何使用AlternationIndex
与ListBox
ES或ListView
S,但我花了几个小时试图让基本背景颜色的ItemsControl
类和似乎没有任何工作。ListBox
我看到的所有示例都ListBoxItem
用作设置背景的样式的目标类型AlternationIndex
- 就像MSDN 中的这个:
<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>
I want to use the ItemsControl
because I do not want the selection functionality and I think restyling a ListBox
to hide it might not be the best choice.
我想使用 ,ItemsControl
因为我不想要选择功能,我认为重新设计 aListBox
以隐藏它可能不是最佳选择。
This is one of the things I was trying:
这是我正在尝试的事情之一:
<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>
The problem I saw was that the visual tree has a list of ContentPresenter
s that have ItemsControl.AlternationIndex
alternate between 0 and 1, but the Grid
in each ContentPresenter
has ItemsControl.AlternationIndex
set to 0.
我看到的问题是可视化树有一个在 0 和 1 之间交替的ContentPresenter
s列表ItemsControl.AlternationIndex
,但Grid
每个中的sContentPresenter
已ItemsControl.AlternationIndex
设置为 0。
There is probably something obvious I am missing...
我可能遗漏了一些明显的东西......
回答by Bubblewrap
The ItemContainerStyle is applied to the elements generated by the ItemsControl: ContentPresenter. The ContentPresenter will in turn contain whatever you put in your ItemTemplate. In the case of a ListBox, the ItemContainerStyle is applied to the generated ListBoxItem.
ItemContainerStyle 应用于由 ItemsControl: ContentPresenter 生成的元素。ContentPresenter 将依次包含您放入 ItemTemplate 的任何内容。在 ListBox 的情况下,ItemContainerStyle 应用于生成的 ListBoxItem。
The AlternationCount is, based on what you posted, only available on these generated items. You cannot use the ItemContainerStyle to set the Grid's background, because the Grid is unknown to that Style.
根据您发布的内容,AlternationCount 仅适用于这些生成的项目。您不能使用 ItemContainerStyle 来设置网格的背景,因为该样式不知道 Grid。
The following would be ideal, but unfortunately ContentPresenter has no background property. It would work for a ListBox (with ListBoxItems) however.
以下是理想的,但不幸的是 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>
So you end up writing a style for the grid which binds to the AlternationIndex of your parent ContentPresenter.
因此,您最终会为绑定到父 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>
回答by Nachbars Lumpi
hm.. After about 2 hours playing around, I finally found the solution that simply works:
嗯.. 玩了大约 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>
I hope this answer helps others to save some time.
我希望这个答案可以帮助其他人节省一些时间。
回答by Becky York
Or, as I found on another post, and it works great for me... You can simply use a binding...
或者,正如我在另一篇文章中发现的那样,它对我很有用......你可以简单地使用绑定......
{Binding
RelativeSource={RelativeSource Mode=TemplatedParent},
Path=(ItemsControl.AlternationIndex)}
NB: remember to add AlterationCount="100" on your ItemsControl
注意:记得在你的 ItemsControl 上添加 AlterationCount="100"
回答by Sean
I don't know how any of the prior answers are legit. I couldn't make any of them work (didn't try Jacobi's though). Anyways, I found the path to enlightenment here: http://www.dotnetcurry.com/wpf/1211/wpf-items-control-advanced-topic, which lead me to adding the following in the xaml.cs code-behind:
我不知道之前的任何答案都是合法的。我无法让它们中的任何一个工作(虽然没有尝试 Jacobi 的)。无论如何,我在这里找到了启蒙之路: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();
}
}
and this in the xaml itself
这在 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>
This was so damn hard to find a working solution to that I'm actually angry
很难找到一个可行的解决方案,我真的很生气
回答by Matt Jacobi
If you don't want to use the DataTemplate
approach, you can create a custom control that uses a ContentControl
as the item container, therefore allowing you to specify a background color.
如果您不想使用该DataTemplate
方法,您可以创建一个使用 aContentControl
作为项目容器的自定义控件,从而允许您指定背景颜色。
Class:
班级:
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;
}
}
Resource Dictionary:
资源字典:
<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>