maui
maui copied to clipboard
Cannot preselect items in CollectionView when it's multiselect on Windows, iOS and macOS
Description
Using a CollectionView it is not possible to preselect items when mode is set to "multiple". It doesn't work on Windows, iOS or macOS however it does work on Android.
Using the method described here: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/selection#multiple-preselection Multiple preselection does not work.
No items in the collection view are pre selected even though the collection in the view model does have the correct values.
I cannot find a way to preselect items in the CollectionView on Windows, iOS or macOS. The only way I can find to select items programmatically from the view model is by using the UpdateSelectedItems method and that only seems to work when triggered manually from a button. It does not work in the constructor or even when used in the onAppearing method.
Steps to Reproduce
- Follow the steps described in the following article to set up a collection view and populate it with preselection in a view model https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/selection#multiple-preselection
- Run the solution and observe the items are not pre selected on Windows, iOS or macOS. However they are preselected on Android.
Use the attached example solution.
- Run the solution.
- Observe that the items are not pre-selected when the app is first executed, on Windows, iOS and macOS.
- Click the button labelled "Select using Binding" and observe the items are NOT selected.
- Click the button labelled "Select using Method" and observe the items ARE selected.
Link to public reproduction project repository
https://github.com/KeithBoynton/CollectionView
Version with bug
7.0.49
Last version that worked well
Unknown/Other
Affected platforms
iOS, Windows, macOS
Affected platform versions
Latest
Did you find any workaround?
No
Relevant log output
No response
I think the issue you're seeing is partially due to an MAUI bug and vaguely worded documentation leading to your code that doesn't work correctly. I've created a repro project showing this: https://github.com/drasticactions/MauiRepros/blob/main/CollectionView/
https://github.com/KeithBoynton/CollectionView/blob/master/ViewModel.cs#L35-L48
You've implemented INotifyPropertyChanged on your view model and directly set the SelectedItems binding to a new ObservableCollection. But this itself doesn't (or shouldn't) do anything. If setting items directly, you must invoke the PropertyChanged event so the UI can update.
https://github.com/drasticactions/MauiRepros/blob/main/CollectionView/ViewModel.cs#L48-L49
Either this or you can change your code to directly update the ObservableCollection list instead of setting it; since then, those events are handled by the UI so it can update.
[RelayCommand]
Task PreSelectUsingBinding()
{
SelectedItems.Clear();
SelectedItems.Add(Items[1]);
SelectedItems.Add(Items[3]);
return Task.CompletedTask;
}
Doing either of these things would fix your "binding" code, the docs imply that "setting" the binding to something else or null would clear it, (https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/selection#clear-selections) that that's "true", but only if you fully wire in INotifyPropertyChanged, which the page doesn't show. If this works on Android without doing that, then that seems more like the bug than the other way around.
That said, there does seem to be an issue, at least with WinUI, where it doesn't auto-set the SelectedItems in the CollectionView even when it is set when the binding was created. Unless I'm missing something else, that should be working and it's not.
@mattleibow @PureWeen Do ya'll have thoughts on this?
Hi @KeithBoynton. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
Yes @drasticactions thats a good catch and is definitely a miss on the documentation too. I've updated the code for that and yes the "binding" button does now work. However, the original issue still remains.
I cannot preselect the items on the collectionview without manual intervention, ie. getting the user to click a button...
- Setting SelectedItems in the constructor does not update the UI
- Setting SelectedItems or updating the existing SelectedItems collection via the OnAppearing override does not update the UI
I've updated the linked repo, where you can see it not working via the constructor or a call in the OnAppearing method
I can confirm there are issues with CollectionView preselected items on iOS and Windows. Android works fine. Even if everything is done correctly with SelectedItems / UpdateSelectedItems.
- Windows: don't work at all
- iOS: partly works - items are actually selected, but it isn't shown visually. If a user selects another item the preselected items will suddenly appear as selected.
Lets not forget macOS too please.
I can confirm there are issues with CollectionView preselected items on iOS and Windows. Android works fine. Even if everything is done correctly with SelectedItems / UpdateSelectedItems.
- Windows: don't work at all
- iOS: partly works - items are actually selected, but it isn't shown visually. If a user selects another item the preselected items will suddenly appear as selected.
I have noticed that the issue is related to VisualStates (Windows). I managed to access the item's visual element and set the visual state manually using VisualStateManager, and it works fine. However, this approach is not intended to be used in production applications. Hope this help isolate the issue.
This is serious issue for us. We have lots of popup menus on Windows which require preselected items. Would be great if it gets some attention.
Mentioning here also that if SelectionMode is set to Multiple, and you try to highlight multiple items with UpdateSelectedItems, then I find on iOS that the items aren't displayed at all!!!
On iOS the selected items logic is tied with the UI elements and I found that it helps setting selected items after the list is loaded into the UI.
Verified this issue with Visual Studio Enterprise 17.9.0 Preview 4. Can repro on Windows platforms with sample project. https://github.com/KeithBoynton/CollectionView
I can not have preselected items in a CollectionView on iOs either. VisualStates are ignored until another item is selected. If anybody has a workaround it would be much appreciated. :)
I can confirm the issues for our project as well. We're building a MAUI App for Windows. We added a CollectionView with SelectionMode Multiple and the preselection of the items selected by the user does not work if we use a custom style for the elements in the CollectionView. The preselection is not applied for the elements which are chosen beforehand. However if the user clicks an item the UI gets updated.
It works using the default style for selected items which is provided by the CollectionView but this style is not visible enough to provide a good user experience and sadly we found no way to customize the default styling. It seems like it is only possible to overwrite it with a custom style.
It would be great and highly appreciated if someone of the developers can look into this issue @mattleibow
Can you try the Loaded event on the CollectionView to select things? I wonder if some platforms need the list to actually be in the layout and on screen...
Can you try the Loaded event on the CollectionView to select things? I wonder if some platforms need the list to actually be in the layout and on screen...
That's my experience with iOS.
The CollectionView in our project is embedded in a ContentView which is used as a input mask for the user to put in Data in Entry fields. The ContentView is embedded in a ContentPage. The Loaded Event of the CollectionView itself gets only triggered once in initial loading of the page. If the ContentView opens the Loaded event of the CollectionView does not get triggered.
I seem to be having this issue on Android.
The workaround with the Loaded event for the CollectionView works for me on iOS. I did not test it on Android yet. Just add the event handler in the constructor of the page. When the loaded event triggers manually set the SelectedItems of the collection from the viewmodel.
It is hacky but at least it works.
public SelectionPage(SelectionViewModel viewModel)
{
InitializeComponent();
_viewModel = viewModel;
BindingContext = viewModel;
ItemCollection.Loaded += ItemCollection_Loaded;
}
private void ItemCollection_Loaded(object? sender, EventArgs e)
{
ItemCollection.SelectedItems = _viewModel.SelectedItems;
}
This code reapplies selection on load. CollectionView.Loaded += OnCollectionViewLoaded;
private void OnCollectionViewLoaded(object? _, EventArgs __)
{
// ISSUE: Workaround for bug where the CollectionView doesn't set initial selection
if (CollectionView.SelectionMode == SelectionMode.Single)
{
var selectedItem = CollectionView.SelectedItem;
CollectionView.SelectedItem = null;
CollectionView.SelectedItem = selectedItem;
}
else if (CollectionView.SelectionMode == SelectionMode.Multiple)
{
var selectedItems = CollectionView.SelectedItems;
CollectionView.SelectedItems = null;
CollectionView.SelectedItems = selectedItems;
}
}
This issue is really bad and it doesn't seem to have any workaround for Windows.
I tried reseting the source multiple times and delay it with TaskCompletionSource after the the VM loads SelectedItems, but nothing works.
private async void collectionView_Loaded(object sender, EventArgs e)
{
await vm.TCS.Task;
collectionView.ItemsSource = null;
collectionView.SelectedItems = null;
collectionView.SetBinding(CollectionView.ItemsSourceProperty, "ItemGroups");
collectionView.SetBinding(CollectionView.SelectedItemsProperty, "SelectedItems");
collectionView.SelectedItems = null;
collectionView.SetBinding(CollectionView.SelectedItemsProperty, "SelectedItems");
//collectionView.SelectedItems = vm.SelectedItems;
//collectionView.UpdateSelectedItems(vm.SelectedItems);
}
Given that CollectionView generates Item views with DataTemplate, I don't see any way to manually update VisualState of each Item either.
I am waiting for a solution more than 15 Month. Meanwhile i am using the sfListView from Syncfusion. You can preselect multiple items, like in collectionview you have to handle them as OberservableCollection
update: it seems, syncfusion has fixed the sfListView garbage collection problem. Pages with that control are correctly disposed now. Don't know how long it's fixed because i gave up checking memory leaks months ago. All my pages and viewmodels, expect shell root's pages, are destructed now.
Hello, I just want to add a precision: the behavior of preselection is also buggy when SelectionMode is set to Single. On Windows, upon CollectionView loading, the selected item is systematically set to null.
It seems that many things broke since MAUI release. Xamarin is now out of support, MS is just pushing us to React Native and Flutter. I've faced so many serious issues the last few months... I have 20 years of experience and never ever before have come across so many issues. Just at the top of my head:
- CollectionView selection is broken
- CarouselView SnapPointsType is not working properly, some time the view snaps to the center some times is off.
- CarouselView VisualStateGroup not working on iOS
- CarourselView SelectedItem not updating
- Button gradient spills outside the control
- Maps control seems to re-render the same markers when the Itemsource is set. and the list goes on