I'm using a WinUI3 ListView like this to load a list of files:
<ListView ItemTemplate="{StaticResource Template2}"
ItemsSource="{x:Bind Files,Mode=OneWay}"
IsItemClickEnabled="True" x:Name="List2" SelectionMode="Multiple" />
<DataTemplate x:Key="Template2" x:DataType="local:FileItem">
<Grid>
.... TextBlocks that bind to properties in FileItem
</Grid>
</DataTemplate>
Now, how do I configure my DataTemplate in order for some (or all) of the items to be selected by default?
Is there a special value in the data template I should use?
You can use the ListViewItem
in your ItemTemplate
.
Let's say your FileItem
looks like this:
public partial class FileItem : ObservableObject
{
[ObservableProperty]
private string _name = string.Empty;
[ObservableProperty]
private bool _isSelected;
}
and your ViewModel:
public partial class MainPageViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<FileItem> _files = new()
{
new FileItem { Name = "File1" },
new FileItem { Name = "File2", IsSelected = true, },
new FileItem { Name = "File3"},
};
}
and in XAML:
<Page.Resources>
<DataTemplate
x:Key="Template2"
x:DataType="local:FileItem">
<ListViewItem IsSelected="{x:Bind IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBlock Text="{x:Bind Name, Mode=OneWay}" />
</ListViewItem>
</DataTemplate>
</Page.Resources>
<ListView
Grid.Row="1"
IsItemClickEnabled="True"
ItemTemplate="{StaticResource Template2}"
ItemsSource="{x:Bind ViewModel.Files, Mode=OneWay}"
SelectionMode="Multiple" />
But unfortunately, this won't work because the ListViewItem
resets its IsSelected
property to false
when it's loaded. I'm not sure if it's a bug or it's by design.
As a workaround, you can do the binding after each ListViewItem
is loaded:
<Page.Resources>
<DataTemplate
x:Key="Template2"
x:DataType="local:FileItem">
<ListViewItem Loaded="ListViewItem_Loaded">
<TextBlock Text="{x:Bind Name, Mode=OneWay}" />
</ListViewItem>
</DataTemplate>
</Page.Resources>
then in code-behind:
private void ListViewItem_Loaded(object sender, RoutedEventArgs e)
{
if (sender is not ListViewItem listViewItem)
{
return;
}
listViewItem.SetBinding(
ListViewItem.IsSelectedProperty,
new Binding
{
Path = new PropertyPath("IsSelected"),
Mode = BindingMode.TwoWay,
Source = listViewItem.DataContext,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
});
}
BTW, I'm using the CommunityToolkit.Mvvm NuGet package for the ViewModels but I hope this gives you an idea how to fix your issue.