web-dev-qa-db-ja.com

ItemsControlでAlternationIndexを使用する方法

AlternationIndexListBoxesまたはListViewsと一緒に使用する方法を示す記事をいくつか見ましたが、ベースで交互の背景色を取得するために数時間を費やしていました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>

ItemsControlを使用したいのは、選択機能が必要ないためです。ListBoxを再スタイルして非表示にするのは、最善の選択ではないかもしれません。

これは私が試していたものの1つです:

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

私が見た問題は、ビジュアルツリーにContentPresentersのリストがあり、ItemsControl.AlternationIndexが0と1の間で交互になっているが、各GridContentPresenterにはItemsControl.AlternationIndexを0に設定します。

おそらく私が見逃している明らかな何かがあります...

29
Filip Skakun

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

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>

この回答が他の人の時間の節約に役立つことを願っています。

26
Nachbars Lumpi

または、別の投稿で見つけたように、それは私にとってはうまくいきます...バインディングを使用するだけで...

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

注意:ItemsControlにAlterationCount = "100"を追加してください。

2
Becky York

私は以前の答えのどれが合法であるか知りません。私はそれらのいずれも機能させることができませんでした(ただし、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();
    }
}

そしてこれは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>

これは、私が実際に怒っているという解決策を見つけるのがとても大変だった

0
Sean

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>
0
Matt Jacobi