Since it seems that there is not easy way to do this, you should keep track of the index in the item (MyData) itself. But if you can't do that, you can try what I came up with. It works. Visual Studio will yell at you but it works.
First, you need to install the CommunityToolkit.WinUI.Extensions NuGet package.
Then:
public partial class ListViewItemElementToIndexConverter : IValueConverter
{
private ListView? OwnerListView { get; set; }
public object Convert(object value, Type targetType, object parameter, string language)
{
var frameworkElement = value as FrameworkElement;
OwnerListView ??= frameworkElement?.FindAscendant<ListView>();
string index = OwnerListView?.Items.IndexOf(frameworkElement?.DataContext).ToString() ?? "-1";
return index;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
<Page.Resources>
<local:ListViewItemElementToIndexConverter x:Key="ListViewItemElementToIndexConverter" />
</Page.Resources>
<ListView ItemsSource="{x:Bind ViewModel.MyDataCollection, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:MyData">
<ListViewItem>
<TextBlock
x:Name="IndexTextBlock"
Text="{x:Bind IndexTextBlock, Mode=OneWay, Converter={StaticResource ListViewItemElementToIndexConverter}}" />
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
UPDATE
You need to wrap the DataTemplate content with a ListViewItem unless the DataContext won't be set.