Search code examples
listviewwindows-10uwpcollectionviewsource

UWP - Filtering ListView with grouping


I have a ListView with grouping. I want to display items in this ListView according to text entered into TextBox. There are many tutorials about filtering a ListView and CollectionViewSource, but they are for WPF not UWP. What I'm doing:

My ListView:

    <ListView x:Name="ContactsListView"
              ItemTemplate="{StaticResource ContactsTemplate}"
              ItemsSource="{x:Bind ContactsViewSource.View}"
              SelectionMode="Single"
              ShowsScrollingPlaceholders="True" >

              <ListView.GroupStyle>
                 <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                       <DataTemplate x:DataType="data:GroupingItem">
                          <TextBlock Text="{x:Bind Key}"
                                     Foreground="Blue"
                                     Style="{ThemeResource TitleTextBlockStyle}"/>
                       </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                 </GroupStyle>
              </ListView.GroupStyle>
    </ListView>

My CollectionViewSource is defined in Page.Resources:

 <CollectionViewSource x:Name="ContactsViewSource"
                       x:Key="src"
                       IsSourceGrouped="True" />

I have created a textChanged event handler for TextBox:

private void SearchBox_TextChanged(object sender, TextChangedEventArgs e) {
    ....
    //here I filter ListView items and add them to CollectionViewSource
    ContactsViewSource.Source = filteredValues;
}

But no change. ListView is not refreshed. I don't know what to do. I wasn't able to find any solution to this problem for UWP.

When assigning data in MainPage constructor it is displaying data. When I don't assign data in constructor but in SearchBox_TextChanged there are no data displayed in ListView.


Solution

  • Do note that x:Bind default behaviour is OneTime! So it won't track any further changes.

    Add x:Bind ContactsViewSource.View, Mode=OneWay to be sure it's tracking changes.

    Also, I would rather add the Source of the CollectionViewSource in XAML like

     <CollectionViewSource x:Name="ContactsViewSource"
                           x:Key="src"
                           Source="{x:Bind FilterdValues, Mode=OneWay}"
                           IsSourceGrouped="True" />
    

    And add that as a property and let the code inherit from INotifyPropertyChanged so that you can change that FilterValues in code instead of always reassigning the ContactsViewSource.Source in code...