C# 在Windows Phone 8.1应用程序中筛选列表视图

C# 在Windows Phone 8.1应用程序中筛选列表视图,c#,xaml,listview,windows-phone,C#,Xaml,Listview,Windows Phone,我正在XAML/C#中开发Windows Phone 8.1应用程序 我有一个listview,它的项目源被设置为名为MusicSource的CollectionViewSource。在C#的后端,我有一个名为source的ObservableCollection,下面的代码通过获取手机上的所有音乐文件来填充它,按艺术家对其进行分组,然后将它们放入CollectionViewSource,在列表视图中显示它们: var folders = await folder.GetFoldersAsync

我正在XAML/C#中开发Windows Phone 8.1应用程序

我有一个listview,它的项目源被设置为名为
MusicSource
CollectionViewSource
。在C#的后端,我有一个名为
source
ObservableCollection
,下面的代码通过获取手机上的所有音乐文件来填充它,按艺术家对其进行分组,然后将它们放入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;
var folders=await folder.GetFoldersAsync();
如果(文件夹!=null)
foreach(文件夹中的var fol)
等待音乐(fol);
var files=await folder.getfileasync();
foreach(文件中的var文件)
{
MusicProperties MusicProperties=await file.Properties.GetMusicProperties异步();
this.source.Add(新音乐((musicProperties.Artist.Length>0)?musicProperties.Artist:“自定义”,(musicProperties.Title.Length>0)?musicProperties.Title:file.Name,(musicProperties.Album.Length>0)?musicProperties.Album:“自定义专辑”,file.Path));
}
itemSource=AlphaKeyGroup.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中得到如下内容:

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;
迈克尔杰克逊

  • 坏的
  • 危险的
  • 惊悚片
  • 怪兽
阿姆

  • 不怕
  • 怪物
当用户在搜索文本框中键入时,应过滤listview并仅显示与搜索文本框中的文本匹配的项目。例如,如果我在搜索框中键入“怪物”,列表视图将立即被过滤,并且仅在“迈克尔·杰克逊”组标题中显示“怪物”,在“阿姆”组标题中显示“怪物”


如何实现这一点?

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

...

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);
            }
        }
    }
}
。。。
var rule=x=>GetTextToFilter(x).IndexOf(filterText,
StringComparison.CurrentCultureInogoreCase)>=0;
foreach(组中的var组)
{
组。可更新项(规则);
}
...
作废可更新项(Func规则)
{
for(int i=0,j=0;i
这样,如果过滤后项目仍然可见,则选择将保持不变。动画看起来是正确的,因为系统将其视为可观察集合上的一系列插入/移除(完整列表刷新将使整个列表被移除和还原,而这将是错误的动画)


它工作得很好(假设AllItems不是数百万行),但在特定情况下,我遇到了奇怪的异常-当
ListView.GroupStyle.HidesIfEmpty=True
和一些(或全部?)组在更新过程中被清除时-Windows.UI.Xaml.dll中的进程崩溃。C#代码中没有捕获异常(未处理的异常和TaskScheduler.UnobservedTaskException是静默的)。事件日志中没有可用的内容。调试器无法显示详细信息,甚至无法附加到失败的进程。如果我添加
wait Task.Delay()
它将更加稳定,但仍可能不时失败。如果我设置ListView.GroupStyle.HidesIfEmpty=False
-所有都稳定工作

嗯,这似乎一点也不难,你所要做的就是先列出你的歌曲列表,然后搜索其中的项目,并将不需要的项目折叠起来! 为了便于工作,请使用listview控件并在其项中进行搜索。
请注意,首先您必须在母控件中缓存所有listview控件,以便将来进行搜索,以避免再次获取所有音乐并禁用搜索模式。

类似于“itemSource=AlphaKeyGroup.CreateGroups(source,CultureInfo.CurrentUICulture,s=>s.Artister,true)”的内容。其中(s=>s.Artister.Contains(“searchedtext”)| | s.Album.Contains(“searchedtext”);问题是,当您更改itemsource时,所有选定的项目都会被取消EdhM。我不确定您想要实现什么,所以我不知道为什么在搜索框中键入时会选择项目。但是,您可以有两个列表框,并将可见性设置为绑定到属性,例如“bool isSearching“。如果isSearching==true,则隐藏listbox1并显示ListBox2。但不确定这将如何影响性能。