Search code examples
c#avalonia

How to know the index of the current element of ItemsRepeater in Avalonia?


I have the following code in my MainWindow.axaml :

<ItemsRepeater Items="{Binding ChannelCollection}">
    <ItemsRepeater.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Value, Mode=TwoWay}" Content="{Binding Name}"></CheckBox>
        </DataTemplate>
    </ItemsRepeater.ItemTemplate>
</ItemsRepeater>

Here I bind to collection of Channels with Name and Value properties. But actual content of my checkbox depends on its index in the collection. I don't want to resolve the Channel myself but want to use converter that maps index to the name. So far I have to know the element index from the axaml code.

I want to have something like this in my Checkbox tag:

Content="{Binding ItemsRepeater.CurrentIndex, Converter={StaticResource IdToNameConverter}}"

How can I do this?


Solution

  • You could use a multi value converter that converts your collection and the element to the name string:

    public class ElementIndexConverter : IMultiValueConverter
    {
        public object Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
        {
            return values[0] is IList list ? $"{list.IndexOf(values[1])}" : "-1";
        }
    }
    

    Then in the view you have to use MultiBinding and pass the collection and the object:

    <ItemsRepeater Items="{Binding ChannelCollection}">
        <ItemsRepeater.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding Value, Mode=TwoWay}">
                        <CheckBox.Content>
                            <MultiBinding Converter="{StaticResource ElementIndexConverter}">
                                <MultiBinding.Bindings>
                                    <Binding Path="$parent[ItemsRepeater].DataContext.ChannelCollection"/>
                                    <Binding Path="."/>
                                </MultiBinding.Bindings>
                            </MultiBinding>
                        </CheckBox.Content>
                    </CheckBox>
                </StackPanel>
            </DataTemplate>
        </ItemsRepeater.ItemTemplate>
    </ItemsRepeater>