如何获取当前ItemsControl项的索引?

her*_*tao 18 c# data-binding wpf itemscontrol

有没有办法获取当前ItemsControl项目的索引WPF

例如,我想做类似的事情:

<ItemsControl>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding current_index}">
            </TextBox>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

所以在此之后,第一个TextBox将显示文本"0",第二个"1",第三个"2" ....

Fis*_*ede 31

我建议看看:

WPF ItemsControl ItemsSource中的当前ListItem索引

它解释了如何解决ItemsControl上没有内置Index属性的事实.

编辑:

我尝试了以下代码:

<Window.Resources>
    <x:Array Type="{x:Type sys:String}" x:Key="MyArray">
        <sys:String>One</sys:String>
        <sys:String>Two</sys:String>
        <sys:String>Three</sys:String>
    </x:Array>
</Window.Resources>
<ItemsControl ItemsSource="{StaticResource MyArray}" AlternationCount="100" >
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex), 
                RelativeSource={RelativeSource TemplatedParent}, 
                StringFormat={}Index is {0}}">
            </TextBlock>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl >
Run Code Online (Sandbox Code Playgroud)

并获得一个包含三个TextBlocks的窗口,如:

[Index is 0]
[Index is 1]
[Index is 2]
Run Code Online (Sandbox Code Playgroud)

  • 对于发现此问题的其他人,我喜欢并使用了 Saykor 的解决方案。我听说您不能依赖始终从零开始的 AlternationCount。感觉像一个黑客。而是使用转换器并将确定索引所需的信息传递给它。 (2认同)
  • @Leonidas:我发现在计算布局时,对于所有项目,AlternationIndex 值经常被传递到我的代码隐藏中,因此它对我来说效果不佳,因为我想要它不仅仅是显示时间绑定。对 ItemsSource 中的项目使用 ReferenceEquals 来确定它们的索引是一种可靠的替代方法。 (2认同)

Max*_*mus 7

看一下这个

 <ItemsControl ItemsSource="{Binding Items}" Name="lista">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock>
                        <TextBlock.Text>
                            <MultiBinding Converter="{StaticResource converter}">
                                <Binding Path="."/>
                                <Binding ElementName="lista" Path="ItemsSource"/>
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
Run Code Online (Sandbox Code Playgroud)

转换器看起来像这样

 public class conv : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ObservableCollection<string> lista = (ObservableCollection<string>)values[1];
        return String.Concat(lista.IndexOf(values[0].ToString()), " ", values[0].ToString());
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是 在此输入图像描述


Say*_*kor 7

在这里我如何获得 ItemIndex

<ItemsControl>
        <ItemsControl.Resources>
            <CollectionViewSource x:Key="ProductItems" Source="{Binding SelectedScanViewModel.Products}">
                <CollectionViewSource.SortDescriptions>
                    <componentModel:SortDescription PropertyName="ProductName" Direction="Ascending"/>
                </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>
        </ItemsControl.Resources>
        <ItemsControl.ItemsSource>
            <Binding Source="{StaticResource ProductItems}"/>
        </ItemsControl.ItemsSource>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel HorizontalAlignment="Center">
                    <TextBlock Text="{Binding ProductName}" HorizontalAlignment="Center" />
                    <TextBox Name="txtFocus" Text="{Binding Qty}" MinWidth="80" HorizontalAlignment="Center"
                                     behaviors:SelectTextOnFocus.Active="True">
                        <TextBox.TabIndex>
                            <MultiBinding Converter="{StaticResource GetIndexMultiConverter}" ConverterParameter="0">
                                <Binding Path="."/>
                                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" Path="ItemsSource"/>
                            </MultiBinding>
                        </TextBox.TabIndex>
                    </TextBox>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="{Binding SelectedScanViewModel.Products.Count}"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
Run Code Online (Sandbox Code Playgroud)

和转换器:

public class GetIndexMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var collection = (ListCollectionView)values[1];
        var itemIndex = collection.IndexOf(values[0]);

        return itemIndex;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException("GetIndexMultiConverter_ConvertBack");
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以将每种类型的集合绑定到 ItemSource,他将更改为 ListCollectionView。因此转换器将适用于不同的集合类型。

xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Run Code Online (Sandbox Code Playgroud)