2014-08-28 58 views
3

我正在使用XAML/C#中的Windows Phone 8.1应用程序。在Windows Phone 8.1应用程序中筛选列表视图

我有一个列表视图,其项目源设置为CollectionViewSource,名为MusicSource。在C#的后端,我有一个ObservableCollection,调用source,下面的代码通过获取手机上的所有音乐文件来填充它,按艺术家对它进行分组,然后将它们放入CollectionViewSource中,这会在列表视图中显示它们:

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.Length > 0) ? musicProperties.Artist : "Custom", (musicProperties.Title.Length > 0) ? musicProperties.Title : file.Name, (musicProperties.Album.Length > 0) ? musicProperties.Album : "Custom Album", file.Path)); 
} 
itemSource = AlphaKeyGroup<Music>.CreateGroups(source, CultureInfo.CurrentUICulture, s => s.Artist, true); 
this.MusicSource.Source = itemSource; 

下面是它的XAML的一面:

<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> 

所以我得到的东西就像在ListView以下几点:

迈克尔·杰克逊

  • 危险
  • 惊悚
  • 怪物

阿姆

  • 不怕
  • 怪物

当用户键入搜索文本框时,应该过滤列表视图并仅显示与搜索文本框中的文本匹配的项目。因此,例如,如果我在搜索框中输入“Monster”,则立即过滤列表视图,并且只在“Michael Jackson”组头中显示“Monster”,在“Eminem”组头中显示“Monster”。

我该怎么做到这一点?

+1

东西沿着“itemSource = AlphaKeyGroup .CreateGroups(source,CultureInfo.CurrentUICulture,s => s.Artist,true).Where(s => s.Artist.Contains(”searchingtext“)|| s .Album.Contains(“searchingtext”); – user3007447 2014-08-28 18:55:29

+0

问题在于当你改变itemsource时,所有选定的项目都被取消选择 – DemCodeLines 2014-08-28 19:53:10

+0

嗯,我不完全确定你想达到什么,所以我不知道为什么您可以在搜索框中输入时选择项目 但是,您可以有两个列表框并将可见性绑定到属性,如“bool isSearching”。如果isSearching == true,则隐藏listbox1并显示listbox 2 不知道如何影响性能,但。 – user3007447 2014-08-29 06:16:42

回答

1

我对Windows 8 Store应用程序有类似的任务 - 当用户键入示例文本时,对分组列表视图进行实时筛选。我制作了一个保存FilterText和Groups的视图模型。组有两个可观察的集合 - AllItems(项目的完整列表)和Items(在屏幕上可见)。当FilterText被更改时,我正在浏览每个组中的每个项目,并确定是否将它保留在Items中。以下是一些代码:

... 

var rule = x => GetTextToFilter(x).IndexOf(filterText, 
       StringComparison.CurrentCultureIgnoreCase) >= 0; 

foreach (var group in Groups) 
{ 
    group.UpdateVisibleItems(rule); 
} 

... 

void UpdateVisibleItems(Func<ItemViewModel, bool> rule) 
{ 
    for (int i = 0, j = 0; i < AllItems.Count; i++) 
    { 
     var item = AllItems[i]; 
     if (rule(item)) 
     { 
      if (j == _Items.Count || (j < _Items.Count && _Items[j] != item)) 
      { 
       _Items.Insert(j, item); 
      } 

      j++; 
     } 
     else 
     { 
      if (j < _Items.Count && _Items[j] == item) 
      { 
       _Items.RemoveAt(j); 
      } 
     } 
    } 
} 

如果项目在过滤后仍然可见,则此方式选择保持不变。动画看起来是正确的,因为系统将其视为可观察集合上的一系列插入/删除(完整列表刷新将使整个列表被删除并恢复,这将导致动画错误)。

它的伟大工程(前提是AllItems不是数百万行),但我打奇怪的例外,在特定情况 - (或全部)时ListView.GroupStyle.HidesIfEmpty=True和某些群体在更新的过程中清理 - 过程中崩溃Windows.UI.Xaml.dll。没有异常被困在C#代码中(UnhandledException和TaskScheduler.UnobservedTaskException是无声的)。在事件日志中没有可用的。调试器无法显示详细信息,甚至无法附加到失败的进程。如果我添加await Task.Delay()它会更稳定,但仍可能会不时失败。如果我设置ListView.GroupStyle.HidesIfEmpty=False - 所有工作稳定!

0

嗯,它看起来并不难,所有你需要做的是首先制作你的歌曲列表,然后在它的项目中搜索并制作不需要的项目COLLAPSED! 为便于工作使用listview控件并在其项目中搜索。 请注意,首先你必须制作母控件中所有列表视图控件的缓存以供将来搜索,以避免再次获取所有音乐并且禁用搜索模式。

相关问题