Scrolling a ListView CollectionViewSource to a group of items based on a search textbox's text in C#

badshar

New member
Aug 27, 2014
26
0
0
Visit site
The following is my XAML code:

<Page.Resources>
<DataTemplate x:Key="GroupTemplate">
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1">
<TextBlock x:Name="SongTitle" Text="{Binding Title}"
Style="{ThemeResource ListViewItemTextBlockStyle}"/>
<TextBlock x:Name="ArtistName" Text="{Binding Album}"
Style="{ThemeResource ListViewItemContentTextBlockStyle}"/>
</StackPanel>
</Grid>
</DataTemplate>

<CollectionViewSource x:Name="MusicSource" IsSourceGrouped="true" />

<DataTemplate x:Key="headerTemplate">
<StackPanel HorizontalAlignment="Stretch" Width="{Binding ActualWidth, ElementName=contentList}">
<TextBlock Text="{Binding Key}" />
</StackPanel>
</DataTemplate>
</Page.Resources>

<Grid>
<SemanticZoom>
<SemanticZoom.ZoomedInView>
<ListView
x:Name="contentList"
SelectionMode="Multiple"
ItemsSource="{Binding Source={StaticResource MusicSource}}"
ItemTemplate="{StaticResource GroupTemplate}">
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="True" HeaderTemplate="{StaticResource headerTemplate}"/>
</ListView.GroupStyle>
</ListView>
</SemanticZoom.ZoomedInView>
</SemanticZoom>
<Border
x:Name="SearchBorder"
Background="White">
<TextBox
x:Name="Search" TextChanged="TextBox_TextChanged" />
</Border>
</Grid>

The following is the C# code behind it:

// imports

namespace Test
{
public sealed partial class Player : Page
{
ObservableCollection<Music> source = new ObservableCollection<Music>();
List<AlphaKeyGroup<Music>> itemSource;

public Player()
{
this.InitializeComponent();
this.SetItemSource();
}

private async Task getMusic(IStorageFolder folder)
{
var folders = await folder.GetFoldersAsync();
if (folders != null)
foreach (var fol in folders)
await getMusic(fol);

var files = await folder.GetFilesAsync();
foreach (var file in files)
{
MusicProperties musicProperties = await file.Properties.GetMusicPropertiesAsync();
this.source.Add(new Music(musicProperties.Artist, musicProperties.Title, musicProperties.Album));
}
itemSource = AlphaKeyGroup<Music>.CreateGroups(source, CultureInfo.CurrentUICulture, s => s.Artist, true);
this.MusicSource.Source = itemSource;
}

public async void SetItemSource()
{
await getMusic(Windows.Storage.KnownFolders.MusicLibrary);
}

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{

}
}
}

As the user types in the textbox, the listview should automatically scroll to the matching group.

The groups are based on Artist, so it's like:

Michael Jackson
- Song 1
- Song 2

Eminem
- Song 1
- Song 2

So if I type "Em", the listview should immediately scroll down to the second group, since that artist "Eminem" comes closest to "Em".

Is this possible?

I am using the AlphaKeyGroup class.
 

luke_f

New member
Oct 6, 2014
81
0
0
Visit site
The ListView has a method ScrollIntoView() which allows you to scroll to a specific item within the list. You can set the second parameter to "Leading", mening that the item shall be scrolled to the top of the list. However, I *think* this only works for the items (tracks in your case) and not for the groups. You could try it with the groups, but if it does not work, try to scroll the first track of the group into view. Hope this helps.
 

Catholic Tech Geek

New member
Feb 2, 2012
130
0
0
Visit site
Yes, this is possible. First, you need a collection of all of the "headers" of each group. Next, when the text changes, you need to search for the first match to what is in the search box within this collection of group headers. Lastly, get the matching group and use the ScrollIntoView() function of the ListView to scroll to the first member of the matching group.
 

Members online

No members online now.

Forum statistics

Threads
323,197
Messages
2,243,435
Members
428,035
Latest member
jacobss