User Tools

Site Tools


notes:uwp:listcontrols

List Controls in XAML

Controls that are able to display collections derive from the ItemsControl:

Object
 └─DependencyObject
   └─UIElement 
     └─FrameworkElement 
       └─Control
         ├─ContentControl
         │ └─SelectorItem (non-instantiable)
         │   ├─ComboBoxItem
         │   ├─FlipViewItem
         │   ├─GridViewItem
         │   ├─ListBoxItem
         │   └─ListViewItem
         ├─ItemsControl - no concept of selection, no scrolling
         └─Selector (non-instantiable) - selection logic
           ├─ComboBox
           ├─FlipView
           ├─ListBox
           └─ListViewBase (non-instantiable)
             ├─GridView
             └─ListView

ItemsControl

  • ItemsControl displays a collection of items.
  • ItemsControl does not have a concept of selection or scrolling.
  • The content property of ItemsControl is Items. It is of type ItemCollection.
  • ItemsControl is a good starting point to create your own data controls.

Properties of the ItemsControl used with data binding:

  • ItemsSource - The source of data. It points to a collection that implements IEnumerable. The ItemsSource property itself is of type object. Note that you may use either the Items property or the ItemsSource property but not both. If you use the ItemsSource property, you may not modify the collection using the Items property.
  • ItemTemplate - A template (of type DataTemplate) for each item.
  • ItemTemplateSelector - Specifies a custom class derived from DataTemplateSelector which allows you to select a specific DataTemplate. Thanks to that different items in the list can have different templates.
  • ItemsPanel - A template (of type ItemsPanelTemplate) for the panel used to layout items in the ItemsControl. There are several special-purpose panels that can be used only as an ItemsPanel to display items in an ItemsControl: ItemsStackPanel, ItemsWrapGrid, VirtualizingStackPanel, and WrapGrid. The default ItemsPanel is a StackPanel.
  • DisplayMemberPath - The name or path of the property that is displayed for each data item.

Properties of the ItemsControl used with styles:

  • ItemContainerStyle (of type Style) - Specifies the style of the item container. This is the style for rendering each item in the collection. For example, the ItemContainerStyle in a GridView control customizes each GridViewItem.
  • ItemContainerStyleSelector - Specifies a custom class deriving from StyleSelector which allows you to select a specific ItemContainerStyle. The StyleSelector class defines a SelectStyle method. This method is invoked whenever an item container is about to be rendered. Thanks to that different items in the list can have different styles.

Properties of the ItemsControl related to grouping:

  • GroupStyleSelector - Similar to ItemContainerStyleSelector but provides a style for each group rather than an item.
  • GroupStyle - Specifies a collection of GroupStyle objects that define the appearance of each level of groups.
  • GroupStyle.HeaderTemplate - Specifies the template that is used to display the group header.
  • GroupStyle.Panel - Specifies the ItemsPanelTemplate used to layout individual ItemTemplate instances.
  • GroupStyle.HidesIfEmpty - Specifies whether items corresponding to empty groups should be displayed.

Example: Snippets showing the use of the ItemsControl's properties:

<ItemsControl>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            ...
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
<ItemsControl>
    <ItemsControl.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    ...
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
            <GroupStyle.Panel>
                <ItemsPanelTemplate>
                    <VariableSizedWrapGrid Orientation="Vertical" />
                </ItemsPanelTemplate>
            </GroupStyle.Panel>
        </GroupStyle>
    </ItemsControl.GroupStyle>
</ItemsControl>

Example: Display items in an ItemsControl:

<!-- without a DataTemplate -->
<ItemsControl>
    <x:String>AAA</x:String>
    <x:String>BBB</x:String>
    <x:String>CCC</x:String>
</ItemsControl>
 
<!-- with a DataTemplate -->
<ItemsControl>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" FontSize="24" Foreground="Green" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <x:String>AAA</x:String>
    <x:String>BBB</x:String>
    <x:String>CCC</x:String>
</ItemsControl>

Example: Wrap an ItemsControl into a ScrollViewer. This adds scrolling functionality to the ItemsControl:

<Grid Background="Beige" Width="300" Height="200">
    <ScrollViewer Margin="4">
        <ItemsControl>
            <x:String>One</x:String>
            <x:String>Two</x:String>
            <x:String>Three</x:String>
            <x:String>Four</x:String>
            <x:String>Five</x:String>
            <x:String>Six</x:String>
            <x:String>Seven</x:String>
            <x:String>Eight</x:String>
            <x:String>Nine</x:String>
            <x:String>Ten</x:String>
        </ItemsControl>
    </ScrollViewer>
</Grid>

Example: Define the ItemsPanelTemplate of an ItemsControl:

<Grid Background="Beige" Width="300" Height="200">
    <ItemsControl HorizontalAlignment="Center">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
 
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock FontSize="40" Foreground="Black" Text="{Binding}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
 
        <x:Int32>1</x:Int32>
        <x:Int32>2</x:Int32>
        <x:Int32>3</x:Int32>
    </ItemsControl>
</Grid>

<Grid Background="Beige" Width="300" Height="300">
    <ItemsControl>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapGrid ItemHeight="100" ItemWidth="100" MaximumRowsOrColumns="2" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.Items>
            <Rectangle Fill="Blue" Width="50" Height="50" />
            <Rectangle Fill="Green" Width="50" Height="50" />
            <Rectangle Fill="Red" Width="50" Height="50" />
            <Rectangle Fill="Magenta" Width="50" Height="50" />
            <Rectangle Fill="Yellow" Width="50" Height="50" />
            <Rectangle Fill="Orange" Width="50" Height="50" />
        </ItemsControl.Items>
    </ItemsControl>
</Grid>

<Grid Background="Beige">
    <ItemsControl>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapGrid ItemHeight="100" ItemWidth="100" MaximumRowsOrColumns="2" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.Items>
            <!-- fit into ItemHeight and ItemWidth -->
            <Ellipse Fill="Blue" Width="100" Height="50" />
            <Ellipse Fill="Green" Width="100" Height="100" />
            <Ellipse Fill="Red" Width="100" Height="100" />
            <!-- oversized and clipped; do not fit into ItemHeight and ItemWidth -->
            <Ellipse Fill="Orange" Width="120" Height="120" />
            <Ellipse Fill="Yellow" Width="200" Height="100" />
            <Ellipse Fill="Magenta" Width="300" Height="200" />
        </ItemsControl.Items>
    </ItemsControl>
</Grid>

ItemsWrapGrid is similar to WrapGrid but implements virtualization:

<Grid>
    <ItemsControl>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsWrapGrid ItemHeight="100" ItemWidth="100" MaximumRowsOrColumns="2" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.Items>
            ...
        </ItemsControl.Items>
    </ItemsControl>
</Grid>

Selector

The Selector class defines the SelectionChanged event. This event is raised whenever the user selects an item from the collection.

Properties of the Selector used with the item selection logic:

  • SelectedIndex - an index of the selected item within a collection (-1 if no item is selected).
  • SelectedItem - the selected item itself (null if no item is selected).
  • SelectedValue - the value of the selected item, obtained by using the SelectedValuePath.

Set the selected item in Selector-derived controls with the SelectedItem or SelectedIndex property.

Set an inital item in Selector-derived controls by setting their SelectedIndex property e.g., SelectedIndex=“0”

ComboBox

Example: Display Book items in a ComboBox:

<ComboBox ItemsSource="{Binding Books}"
          ItemTemplate="{StaticResource BookTemplate}"
          SelectedItem="{Binding SelectedBook, Mode=TwoWay}"
          SelectionChanged="BookComboBox_SelectionChanged" />
private void BookComboBox_SelectionChanged(object sender, SelectionChangedEventArgs args)
{
    if (args.AddedItems.Count > 0)
    {
        Book book = args.AddedItems[0] as Book;
        // ...
    }
}

Example: Define ComboBox's items in XAML:

<ComboBox Header="Select a name" 
          SelectedIndex="0"
          SelectionChanged="ComboBox_SelectionChanged">
    <ComboBoxItem Content="John" />
    <ComboBoxItem Content="Mike" />
    <ComboBoxItem Content="Sophia" />
    <ComboBoxItem Content="Derek" />
</ComboBox>
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs args)
{
    var comboBox = sender as ComboBox;
    string name = (comboBox.SelectedItem as ComboBoxItem).Content as string;
    Debug.WriteLine(name);
}

ComboBox supports the PlaceholderText property.

Example: Placeholder text in a ComboBox and a PasswordBox:

<StackPanel>
    <PasswordBox Header="Password" PlaceholderText="Enter your password" />
    <ComboBox Header="Unusual mammals" PlaceholderText="Pick a mammal">
        <x:String>Platypus</x:String>
        <x:String>Echidna</x:String>
        <x:String>Aardvark</x:String>
        <x:String>Hyrax</x:String>
    </ComboBox>
</StackPanel>

FlipView

Example: A simple FlipView:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:TestApp">
 
    <Grid>
        <FlipView ItemsSource="{x:Bind Glaciers}">
            <FlipView.ItemTemplate>
                <DataTemplate x:DataType="local:Glacier">
                    <Grid>
                        <Image Source="{x:Bind ImageUri}" Stretch="UniformToFill" />
                        <Border Background="#A5000000" Height="80" VerticalAlignment="Bottom">
                            <TextBlock Text="{x:Bind Title}" FontSize="27" Padding="20" Foreground="White" />
                        </Border>
                    </Grid>
                </DataTemplate>
            </FlipView.ItemTemplate>
        </FlipView>
    </Grid>
</Page>
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
 
namespace TestApp
{
    public sealed partial class MainPage : Page
    {
        public ObservableCollection<Glacier> Glaciers { get; private set; }
 
        public MainPage()
        {
            this.InitializeComponent();
 
            Glaciers = new ObservableCollection<Glacier>();
 
            Loaded += MainPage_Loaded;
        }
 
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            Glaciers.Clear();
            Glaciers.Add(new Glacier { ImageUri = "/Assets/glacier1.jpg", Title = "Glacier #1" });
            Glaciers.Add(new Glacier { ImageUri = "/Assets/glacier2.jpg", Title = "Glacier #2" });
            Glaciers.Add(new Glacier { ImageUri = "/Assets/glacier3.jpg", Title = "Glacier #3" });
        }
    }
 
    public class Glacier
    {
        public string ImageUri { get; set; }
        public string Title { get; set; }
    }
}

Example: A FlipView with a custom ItemContainerStyle and a SelectionChanged event handler:

<FlipView ItemsSource="{x:Bind Data}" 
          SelectionChanged="FlipView_SelectionChanged">
    <FlipView.ItemContainerStyle>
        <Style TargetType="FlipViewItem">
            <Setter Property="Margin" Value="80,0,0,0"/>
        </Style>
    </FlipView.ItemContainerStyle>
    <FlipView.ItemTemplate>
        <DataTemplate>
            ...
        </DataTemplate>
    </FlipView.ItemTemplate>
</FlipView>
private void FlipView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // ...
}

GridView and ListView

Frequently used properties of GridView and ListView derived from ListViewBase:

  • SelectionMode (default: Single) - By default, a user can select a single item. You can set the SelectionMode property to a None, Single, Multiple, or Extended enumeration value to enable multi-selection or to disable selection. When multiple selection is enabled, use SelectedItems to iterate through the items.
  • IsSwipeEnabled (default: True) - Indicates whether the selection of items with the swipe gesture is enabled.
  • IsItemClickEnabled (default: False) - Indicates whether items can raise an ItemClick event in response to interaction. If you set the IsItemClickEnabled property to true, you must set the SelectionMode property to ListViewSelectionMode.None.

Working with GridView / ListView:

  • Populate GridView / ListView by adding objects directly to its Items collection or by binding its ItemsSource property to a data source.
  • When you tap an item, that item is selected and GridView / ListView fires a SelectionChanged event.
  • You can specify the look of the ListViewItem by setting the ListView's ItemContainerStyle property to a Style with a TargetType of ListViewItem.
  • You can specify the look of the GridViewItem by setting the GridView's ItemContainerStyle property to a Style with a TargetType of GridViewItem.

Events related to Drag & Drop:

  • DragOver
  • Drop
  • DragLeave

If the data source of a GridView / ListView uses an ObservableCollection the re-ordering of its items is reflected in the data source. It is achieved by setting the following properties to True:

  • CanReorderItems
  • CanDragItems
  • AllowDrop

Examples of customizing ItemContainerStyle:

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="Padding" Value="0" />
        </Style>
    </ListView.ItemContainerStyle>
</ListView>
<GridView>
    <GridView.ItemContainerStyle>
        <Style TargetType="GridViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="Margin" Value="4" />
        </Style>
    </GridView.ItemContainerStyle>
</GridView>

Example: Stretch ListView's items over the entire width of a container:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:TestApp">
    <Grid>
        <ListView ItemsSource="{x:Bind Books}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                    <Setter Property="Padding" Value="0"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Book">
                    <StackPanel>
                        <TextBlock Text="{x:Bind Title}" FontWeight="Bold" />
                        <TextBlock Text="{x:Bind Author}" FontStyle="Italic" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

Example: Respond to the ItemClick event using a ListView. The same code would be for a GridView:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:TestApp">
    <Grid>
        <ListView ItemsSource="{x:Bind Books}"
                  SelectionMode="None"
                  IsSwipeEnabled="False"
                  IsItemClickEnabled="True"
                  ItemClick="ListView_ItemClick">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Book">
                    <StackPanel>
                        <TextBlock Text="{x:Bind Title}" FontWeight="Bold" />
                        <TextBlock Text="{x:Bind Author}" FontStyle="Italic" />
                        <Rectangle Height="2" Fill="Gray" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>
using System.Collections.ObjectModel;
using System.Diagnostics;
using Windows.UI.Xaml.Controls;
 
namespace TestApp
{
    public sealed partial class MainPage : Page
    {
        public ObservableCollection<Book> Books { get; private set; }
 
        public MainPage()
        {
            this.InitializeComponent();
 
            Books = new ObservableCollection<Book>();
 
            Loaded += (sender, args) =>
            {
                Books.Add(new Book { Title = "AAA", Author = "Author1" });
                Books.Add(new Book { Title = "BBB", Author = "Author2" });
                Books.Add(new Book { Title = "CCC", Author = "Author3" });
            };
        }
 
        private void ListView_ItemClick(object sender, ItemClickEventArgs args)
        {
            Book selectedBook = args.ClickedItem as Book;
            if (selectedBook != null)
            {
                Debug.WriteLine(selectedBook.ToString());
            }
        }
    }
 
    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
 
        public override string ToString()
        {
            return $"Book: Title = \"{Title}\", Author = {Author}";
        }
    }
}

Example: Grouping in a ListView:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:TestApp">
 
    <Page.Resources>
        <CollectionViewSource x:Name="BookCollectionViewSource" IsSourceGrouped="true" />
    </Page.Resources>
 
    <ListView ItemsSource="{Binding Source={StaticResource BookCollectionViewSource}}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:Book">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{x:Bind Title, Mode=OneWay}" />
                    <TextBlock Text="-" Padding="8,0,8,0" />
                    <TextBlock Text="{x:Bind Author}" />
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate x:DataType="local:BooksByCategory">
                        <TextBlock Text="{x:Bind Category}" FontWeight="Bold" />
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>
    </ListView>
</Page>
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
 
namespace TestApp
{
    public sealed partial class MainPage : Page
    {
 
        public MainPage()
        {
            this.InitializeComponent();
 
            Loaded += (sender, args) =>
            {
                BookCollectionViewSource.Source = BookRepository.GroupedBooks;
            };
        }
    }
}

This is the BookRepository class used in the above example:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
 
namespace TestApp
{
    public class Book : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        private string title;
        public string Title
        {
            get
            {
                return title;
            }
 
            set
            {
                if (value != title)
                {
                    title = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Title"));
                }
            }
        }
        public string Author { get; set; }
        public string Category { get; set; }
 
        public override string ToString()
        {
            return $"Selected book: Title = \"{Title}\", Author = {Author}, Category = {Category}";
        }
    }
 
    public class BooksByCategory : ObservableCollection<Book>
    {
        public string Category { get; set; }
    }
 
    public static class BookRepository
    {
        public static ObservableCollection<BooksByCategory> GroupedBooks { get; private set; }
 
        static BookRepository()
        {
            var books = new List<Book>();
 
            books.Add(new Book { Title = "AAA", Author = "Author1", Category = "1" });
            books.Add(new Book { Title = "BBB", Author = "Author2", Category = "2" });
            books.Add(new Book { Title = "CCC", Author = "Author3", Category = "1" });
            books.Add(new Book { Title = "DDD", Author = "Author4", Category = "3" });
            books.Add(new Book { Title = "EEE", Author = "Author5", Category = "1" });
            books.Add(new Book { Title = "FFF", Author = "Author6", Category = "1" });
            books.Add(new Book { Title = "GGG", Author = "Author7", Category = "2" });
            books.Add(new Book { Title = "HHH", Author = "Author8", Category = "1" });
            books.Add(new Book { Title = "III", Author = "Author9", Category = "3" });
            books.Add(new Book { Title = "JJJ", Author = "Author10", Category = "3" });
 
            GroupedBooks = new ObservableCollection<BooksByCategory>();
 
            var query = from book in books
                        orderby book.Category
                        group book by book.Category;
 
            foreach (var group in query)
            {
                BooksByCategory booksByCategory = new BooksByCategory();
                booksByCategory.Category = group.Key;
                foreach (Book book in group)
                    booksByCategory.Add(book);
                GroupedBooks.Add(booksByCategory);
            }
        }
    }
}

The GroupedBooks collection uses as nested ObservableCollection. It means that you can add new items and they will be automatically reflected in the UI:

BookRepository.GroupedBooks[2].Add(new Book { Title = "ZZZ", Author = "Author100", Category = "2" });

You can also updated the item's properties if they support INotifyPropertyChanged:

BookRepository.GroupedBooks[0][2].Title = "NEW BOOK";

SemanticZoom

Provide a GridView or a ListView for the ZoomedOutView and the ZoomedInView sections.

<SemanticZoom x:Name="SemanticZoom1" 
              ScrollViewer.HorizontalScrollMode="Disabled" 
              VerticalContentAlignment="Stretch">
    <ZoomedOutView>
        <ListView ...>
    </ZoomedOutView>
    <ZoomedInView>
        <GridView  ScrollViewer.IsHorizontalScrollChainingEnabled="False" ...>
    </ZoomedInView>
</SemanticZoom>
// Populate the items in the zoom-out view.
(SemanticZoom1.ZoomedOutView as ListViewBase).ItemsSource = collection;
 
// Set the selected item.
(SemanticZoom1.ZoomedOutView as ListViewBase).SelectedItem = null;

Example: Go back to the zoom-in view if we are in the zoom-out view:

if (!SemanticZoom1.IsZoomedInViewActive)
{
    SemanticZoom1.ViewChangeStarted -= ServiceCallsSemanticZoom_ViewChangeStarted;
    SemanticZoom1.ToggleActiveView();
    SemanticZoom1.ViewChangeStarted += ServiceCallsSemanticZoom_ViewChangeStarted;
}

Win10 Update: The default action to switch between the zoomed-in view and the zoomed-out view is to tap on a group header in the zoomed-in view. This is a change from Windows 8.1, which used the pinch gesture to zoom. To change views using pinch-to-zoom, set ScrollViewer.ZoomMode=“Enabled” on the SemanticZoom's internal ScrollViewer.

New in Windows 10

MSDN:

  • AreStickyGroupHeadersEnabled property - When you show grouped data in a ListView or GridView, the group headers remain visible when the list is scrolled. You can set the AreStickyGroupHeadersEnabled property on ItemsStackPanel and ItemsWrapGrid to control this behavior.
  • GroupHeaderContainerFromItemContainer method - When you show grouped data in an ItemsControl, you can call the GroupHeaderContainerFromItemContainer method to get a reference to the parent header for the group.
  • ChoosingGroupHeaderContainer event - The ChoosingGroupHeaderContainer event on ListViewBase lets you set state on the group headers in a ListView or GridView.
  • ChoosingItemContainer event - The ChoosingItemContainer event on ListViewBase gives you greater control over UI virtualization in a ListView or GridView. Use this event in conjunction with the ContainerContentChanging event to maintain your own queue of recycled containers from which to draw upon as needed.
  • ListViewItemPresenter and GridViewItemPresenter have new properties that let you customize visuals for list items: CheckBoxBrush, CheckMode, FocusSecondaryBorderBrush, PointerOverForeground, PressedBackground, and SelectedPressedBackground.
notes/uwp/listcontrols.txt · Last modified: 2017/04/03 by leszek