1

I want to create a horizontally scrollable ListView with a selection indicator located at the top or bottom. Can I achieve that by restyling ListViewItemPresenter or anyhow else reusing it?

1
  • I suggest you could try to customize the ControlTemplate of the ListViewItem. You can modify properties on the ListViewItemPresenter to control the selection check box, item positioning, and brush colors for visual states. Commented Dec 10, 2024 at 3:32

3 Answers 3

2

I'm not sure if you can restyle ListViewItemPresenter.

The selection indicator is a Border with no name, so you need to find it by yourself. In the example below, I'm using the CommunityToolkit.WinUI.Extensions NuGet package.

private void MemberListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (sender is not ListView listView ||
        listView.ContainerFromItem(listView.SelectedItem) is not ListViewItem selectedListViewItem ||
        selectedListViewItem.FindDescendant<ListViewItemPresenter>() is not { } selectedListViewItemPresenter ||
        selectedListViewItemPresenter.FindDescendants().OfType<Border>().LastOrDefault() is not Border selectionIndicator)
    {
        return;
    }

    selectionIndicator.Width = 64;
    selectionIndicator.Height = 3;
    selectionIndicator.Margin = new Thickness(0, 0, 0, -8);
    selectionIndicator.HorizontalAlignment = HorizontalAlignment.Center;
    selectionIndicator.VerticalAlignment = VerticalAlignment.Bottom;
}
Sign up to request clarification or add additional context in comments.

1 Comment

If this answer was helpful, please accept it so we can close this session.
0

Perhaps you should use a GridView instead? Set the Orientation to Vertical and the MaximumRowsOrColumns to 1 (weird name, but since it is vertical you can have multiple columns).

This will allow you to scroll horizontally using the mouse scrollwheel and change the selected item using the left/right keys or clicking.

<GridView x:Name="HorizontalList"
    ItemsSource="{x:Bind MyList, Mode=OneWay}"
    ScrollViewer.HorizontalScrollMode="Enabled"
    ScrollViewer.HorizontalScrollBarVisibility="Visible"
    ScrollViewer.VerticalScrollMode="Disabled"
    ScrollViewer.VerticalScrollBarVisibility="Hidden">
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid Orientation="Vertical"
                       MaximumRowsOrColumns="1" 
                ItemWidth="150"
                ItemHeight="150" />
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
</GridView>

enter image description here

Comments

0

Consider using the SelectorBar control. It already has logic for selection indicator that could be restyled and repositioned. The SelectorBar is typically meant for navigation, but it could work for this purpose as a collection control instead. Unfortunately, it does not support data virtualization or an ItemsSource property, which could be limiting depending on your use case. I suggest using with a relatively known/small quantity of items.

You can see a working example in the WinUI 3 gallery app: https://apps.microsoft.com/detail/9P3JFPWWDZRC?hl=en-us&gl=US&ocid=pdpshare

Here is a link to the default style for SelectorBar on GitHub: https://github.com/microsoft/microsoft-ui-xaml/blob/main/src/controls/dev/SelectorBar/SelectorBar.xaml

API Reference: https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.selectorbar

Design docs: https://learn.microsoft.com/en-us/windows/apps/design/controls/selector-bar

1 Comment

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.