【WPF】ListBoxItemのインデックスをContextMenuのCommandParameterにBindingする方法


ListBoxのインデックス

ListBoxのインデックスを取得する方法

ListBoxのインデックスはListBoxAlternationCountプロパティとAlternationIndex添付プロパティの組み合わせで取得できます。

{Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}"}

参考:
https://qiita.com/tera1707/items/791bdb887eae4c0ea6a4

ContextMenuでの対応

しかし、ContextMenuではツリーが別になるためPlacementTargetなどを駆使してDataContextなどを受け渡す必要があります。

そうするとListBoxItemを取得できるのはContextMenu.PlacementTargetになりますが、PlacementTarget.(ItemsControl.AlternationIndex)とすることでAlternationIndex添付プロパティが取得できます。

<ListBox
    ItemsSource="{Binding Items}"
    AlternationCount="1000">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter
                Property="Tag"
                Value="{Binding DataContext,RelativeSource={RelativeSource AncestorType=Window}}"/>
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                        <MenuItem
                            Header="{x:Static properties:Resources.Delete}"
                            Command="{Binding RemoveCommand}"
                            CommandParameter="{Binding PlacementTarget.(ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                            />
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>