问题
I have an ItemsControl nested in the DataTemplate of another ItemsControl. This seemed like the easiest way to display a grid of numbers from a two-dimensional array, which it did very nicely. The problem I have is that I want to change the color a particular number in the grid. I was hoping to trigger off the AlternationIndex of both ItemsControls, so I can identify exactly which number to highlight.
In the DataContext for the parent ItemsControl I have a 2-D array of integers like this:
public int[][] Grid
{
get { return _grid; }
}
_grid is initialized to a 20x20 array of numbers.
Here is my XAML for the ItemsControls:
<ItemsControl Grid.Row="1"
Margin="5"
Name="RowItems"
ItemsSource="{Binding Path=Grid}"
AlternationCount="20"
HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl Name="ColumnItems"
ItemsSource="{Binding}"
AlternationCount="20">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
Margin="0"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="4,2"
Text="{Binding StringFormat={}{0:D2}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Mode=TemplatedParent}}"
Value="8"/>
<Condition Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource FindAncestor, AncestorLevel=2, AncestorType={x:Type ItemsControl}}}"
Value="6"/>
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" Value="Red"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I can easily get an entire column of the numbers to be colored red if I leave the second condition off the MultiDataTrigger, but I can't get the second condition to work. Any thoughts on how I can do this? I can probably do it with a DataGrid or something, but now I'm really interested in how to do this binding...if it is even possible.
UPDATE:
@d.moncada gave me the hint I needed to figure out what I had done wrong. Instead of looking for an ancestor of type ItemsControl, I needed to look for ContentPresenter.
回答1:
Here you go. I was able to achieve this by looking for the ContentPresenter
rather than the ItemsControl
.
<ItemsControl Grid.Row="1"
Margin="5"
Name="RowItems"
ItemsSource="{Binding Path=Grid}"
AlternationCount="20"
HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl Name="ColumnItems"
ItemsSource="{Binding}"
AlternationCount="20">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
Margin="0"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="4,2"
Text="{Binding StringFormat={}{0:D2}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource TemplatedParent}}" Value="8"/>
<Condition Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource FindAncestor, AncestorLevel=2, AncestorType={x:Type ContentPresenter}}}" Value="6"/>
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" Value="Red"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
来源:https://stackoverflow.com/questions/25084231/binding-to-alternationcount-of-itemscontrol-from-itemtemplate-of-a-nested-itemsc