I am displaying a ListView using WinUI3. I am showing an array of structs, but is it possible to display an array index that is not part of the struct in XAML?
<ListView>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:MyData">
<TextBlock Text="{x:Bind Index}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I saw that in WPF, you can do it like the following, but it results in an error in WinUI3. Is there no such method in WinUI3?
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=(ItemsControl.AlternationIndex)}" />
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.