Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the index of the current ItemsControl item?

Is there any way to get the index of the current ItemsControl item in WPF?

For example, I want to do something like:

<ItemsControl>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding current_index}">
            </TextBox>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

so that after this, the first TextBox will show text "0", second "1", third "2" ....

like image 208
herohuyongtao Avatar asked Mar 13 '14 12:03

herohuyongtao


2 Answers

I would suggest looking at:

WPF ItemsControl the current ListItem Index in the ItemsSource

It explains how to work around the fact that there isn't a built in Index property on the ItemsControl.

EDIT:

I tried the following code:

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

And get a window with three TextBlocks like:

[Index is 0]
[Index is 1]
[Index is 2]
like image 82
FishySwede Avatar answered Nov 14 '22 00:11

FishySwede


Here how I get 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>

And the converter:

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");
    }
}

By this way you can bind every type of collection to the ItemSource and he will be change to ListCollectionView. So the converter will work for different collection type.

xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
like image 9
Saykor Avatar answered Nov 14 '22 01:11

Saykor