Binding to AlternationCount of ItemsControl from I

2019-08-21 00:03发布

问题:

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>