Microsoft-ui-xaml: Proposal: Add selection handling to ItemsRepeater by enabling registering SelectionModel to ItemsRepeater

Created on 10 Mar 2020  路  12Comments  路  Source: microsoft/microsoft-ui-xaml

Proposal: Add selection handling to ItemsRepeater by enabling registering SelectionModel to ItemsRepeater

Summary


Currently SelectionModel and ItemsRepeater live two different spaces and do not interact with each other, however are still under the same namespace.

Rationale

  • If one wants to use the selection model, they have to implement selection handling pretty much themselves using the SelectionModel, this is a large drawback compared to GridView or ListView
  • Currently it is a bit confusing, why this even is in the ItemsRepeater project, as it does not interact with the repeater and vice versa

Scope


| Capability | Priority |
| :---------- | :------- |
| Enable adding a SelectionModel to ItemsRepeater | Must |
| Make using selection model easier | Should |

Important Notes

```c#
//*** Possible API: ***//

// Setup repeater
ItemsRepeater myRepeater = new ItemsRepeater()
{
// ...
};

// Setup selection model
SelectionModel mySelectionModel = new SelectionModel();
mySelectionModel.SingleSelect = true;

// Registers the selection model to the ItemsRepeater
// This will also set the selection models ItemsSource to that of the repeater
myRepeater.SelectionModel = mySelectionModel;

mySelectionModel.SelectAt(0);

// This sets the repeaters items source AND the items source of the selection model
myRepeater.ItemsSource = ... ;
```

Open Questions

area-ItemsRepeater feature proposal team-Controls

All 12 comments

@chingucoding Thanks for the proposal. The selection model is intentionally decoupled from ItemsRepeater. Think of these as building blocks that can be put together to build other controls. There are several scenarios where we do not want to use selection or a container for example where having these as part of the building blocks start to affect perf unnecessarily.

ListView/GridView are very different beasts compared to ItemsRepeater and support a lot of features that ItemsRepeater does not support out of the box (needs some wiring to achieve). For starters, ItemsRepeater derives from FrameworkElement and is more comparable to a panel than a control.

What I believe you are asking for is the next layer of controls that put these building blocks together to provide a simpler usage without having to worry about wiring things up every time.

@anawishnoff is looking at the next steps here (ItemsView/DataGrid etc).

Yes that makes sense. However if one wants to use a different layout, it might be a bit off-putting having to "implementing" everything, Are there plans to maybe provide something like "flavors" of the ItemsRepeater? E.g. One could have SelectionModel integrated.

Also where can I find the documentation for the SelectionModel? I didn't find anything for that.

Good question about the docs regarding the SelectionModel I was looking into this as well :-)

As @ranjeshj said, on first thought, I would keep the ItemsRepeater decoupled from the SelectionModel and also not provide several versions of the ItemsRepeater coupled with a different selection model each. Rather, we could think about scenarios where the existing controls to display data (such as ListView) are too unflexible in a single dimension and see if those can be made a bit more flexible. These new collection controls could indeed be made up of several independent components to drive new, more flexible controls without having to decide between current ListView/GridView controls and the ItemsRepeater approach from the ground up.

In some cases there might just be a single reason why the current controls won't suffice and we should identify these cases and see if we can provide more flexible data controls so that developers can still utilize as much of the in-built features as possible without having to re-create features they are perfectly fine with.

@Felix-Dev My ideas was not about having different selection models, but rather about having the bare bones ItemsRepeater, one with SelectionModel integrated, one with Scrolling integrated etc.

The main reason I would choose the ItemsRepeater is because I can use different layouts, that I don' t think I can use with the ItemsRepeater e.g. UniformGridLayout. Beside a different layout and performance, I don't think many people would choose ItemsRepeater instead of existing controls.

@chingucoding The issue that I see with several versions of ItemsRepeater (or different controls with different features packaged with ItemsRepeater) is that it does not compose well. If there was one with Scrolling integrated and one with Selection, then we cannot put those two together to get one that scrolls and provides selection. Obviously we could create another which has both, but that does not scale.

Can you provide more details on what you meant by 'registering' a selection model ? Selection model is a great example of how multiple things can get tied together. For selection to work we need the following pieces (what I initially meant by wire-up)

  1. ItemContainer
    (a) To show the selection visuals
    (b) To handle interactions, keyboard, mouse, touch etc to select/deselect
  2. Automation peers
    (a) ItemContainerAutomationPeer - to enable selection to work with automation
    (b) Automation peer for the control itself (or ItemsRepeater's automation peer) needs to support SelectionContiner pattern.
  3. Some way to track indices on the container. This can be either flat or nested (think index paths for TreeView, Hierarchical/grouping scenarios)

Perhaps having some of these pieces built can reduce the pain creating them for every scenario.

Good point about documentation. SelectionModel API is currently in preview and we need to work on documentation before it becomes public.

@chingucoding @Felix-Dev @ranjeshj

I'd like to chime in here and echo @ranjeshj 's point above about having different versions of ItemsRepeater not compose well. If I understand your situation, you want to create a virtualizing custom layout (can only be done through ItemsRepeater) but don't want to have to spend extra time implementing things like selection?

If that's the case, this is definitely something that we're looking into! Although I feel that it's important to keep selection, scrolling, and similar services decoupled from ItemsRepeater, we are looking on how to use ItemsRepeater in the future of the platform, specifically as a building block for more collections controls. I definitely want to allow devs to get the goodness of ItemsRepeater (perf, customizability) without having to implement things that they wouldn't need to in controls like ListView or GridView. However, since ItemsRepeater is truly a "building block" control, we don't want to bloat its API with properties and services that will only be helpful in occasional use cases.

It's great to hear this feedback! The ItemsRepeater documentation may help as it uses a SelectionModel, but I will look into making sure that those docs are published ASAP as well.

@ranjeshj , if we would wire it up that way, it would be quite an overhead, agreed. Maybe a compromise would be using events and such and let the devs implement the gaps such as selection highlighting. Though there would still be a lot of logic the repeater needs to handle. However currently, all of that would need to be developed by oneself, so having some templates/helpers/classes to use would definitely make it easier to adopt the ItemsRepeater.

@anawishnoff Yes, I was trying to use a different layout. The best way for me would have been: I would swap out the old control e.g. a GridView for the new ItemsRepeater, specify the layout, add a SelectionModel and it works as expected. But for the SelectionModel to work, I would have to add multiple listeners and handle the selection logic myself, including highlighting. Maybe adding a SelectionModel property is not the best solution, but in the current state, at least for me, adding a SelectionModel is not worth the effort for the new layouts I could use.

Adding @ojhad who did a lot of this work for NavigationView, @StephenLPeters who looked at it for RadioButtons and @teaP for TabView. Definitely agree that there is room for improving the experience and potential for a lot of sharing.

@chingucoding @anawishnoff @ranjeshj It's a bit hard to visualize for me right now how - for selection models - sharing could look like since the selection model won't come with its own selection visuals, keyboard listeners and automation support. The model also doesn't know about the layout structure of the underlying data (flast list, hierarchical,...). The layout will affect the selection model though (i.e. in treview, selecting parent node also selects the child nodes in multi-selection).

As we get more freedom with ItemsRepeater and how to create data layouts I find it somewhat unclear right now how some default provided selection model could fit into this picture. For example, items might be arranged in a grid after all, but it's not a GridView in use which has its own in-built selection logic, but a combination of ItemsRepeater(s) and layout panels. So there might have to be multiple selection models to cover common data layouts (one for flat layouts, one for hierarchical layouts,...) which doesn't seem "correct" to me.

That said, I have yet to build a control using the ItemsRepeater so perhaps I'm missing out on some crucial experience here.

@Felix-Dev Here is a quick description of what SelectionModel does. The current selection model we have in preview is a completely decoupled component that only tracks selection state (i.e. which indices are selected). Tracking selection state in itself is a complex process since selection can change, the underlying collection can change (this will change selected indices but we want selected items to remain the same) and also we cannot track individual indices because if you had a large collection and did select all, you can end up consuming more memory than needed (need to track index ranges). You can also think of nested collections (tree view as an example or hierarchical navigation view) where tracking selection becomes even more complex. We also want to be able to support multiple and extended selection where it should be possible to start selection at say index 1.2.3 and until 2.2.4. The current selection model essentially is designed to do this tracking. You can give it a collection (Source), select certain indices/index paths, select ranges of indices, and ask which indices are selected/not. It will make sure that the correct indices are kept up to date in the event of collection changes. That is all it does.

SelectionModel does not do anything with selection visuals or containers, so it is not something tied to layout. If you had a custom layout and containers, you can still tell selection model when an item is clicked what its index is and let it track that. Extended selection/range selection might not make sense in layouts that are not contiguous (increasing indices laid out one after the other) - but that is essentially the issue with building a packaged control (some combinations might not make sense).

There are handful of sample usages here in the test app in case you are interested in seeing how it all fits together.

@ranjeshj Thanks for the explanation.

Was this page helpful?
0 / 5 - 0 ratings