【问题标题】:Unable to hide Listview items无法隐藏 Listview 项目
【发布时间】:2014-09-18 10:12:59
【问题描述】:

我正在开发通用 Windows 应用程序。它包含一个 ListView 来显示一组术语及其定义。 ListView 绑定到 XAML 部分中的 DataSource.cs 文件。 ListView 显示正确。

需要添加一个搜索框以在输入关键字时过滤掉 ListView 项目。我已确认搜索框能够通过使用 Debug.Writeline("")

我面临的问题是我无法隐藏搜索框未选择的项目。实际搜索发生在包含 if 块的 foreach 循环内。因此,我的想法是将 ListView.slectedItem 隐藏在相应的 else 块中。 问题是这种方法会抛出一个异常,上面写着,

“System.Exception”类型的第一次机会异常发生在 mscorlib.dll 中 mscorlib.dll 中出现“System.Exception”类型的异常,但未在用户代码中处理 附加信息:灾难性故障(HRESULT 异常:0x8000FFFF (E_UNEXPECTED))

程序“XXXX.exe”已退出,代码为 -1 (0xffffffff)。

这里我已经提供了代码。

XAML

<ListView x:Name="ItemListView" 
    Margin="0,0,0,4" 
    Height="Auto" 
    ItemTemplate="{StaticResource MessageListImageTemplate}" 
    ShowsScrollingPlaceholders="False"
    ContainerContentChanging="ItemListView_ContainerContentChanging"
    ItemClick="ItemListView_ItemClick"        
    IsItemClickEnabled="True" 
    SelectionMode="None">

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                <Setter Property="Padding" Value="0,0,0,20"/>
            </Style>
        </ListView.ItemContainerStyle>

</ListView>

<SearchBox  
    x:Name="search" 
    PlaceholderText="Search for a term"  
    SuggestionsRequested="search_SuggestionsRequested" 
    SearchHistoryEnabled="False" `
    Grid.Row="1"
    HorizontalAlignment="Left" 
    VerticalAlignment="Center" 
    Margin="50,0,0,0" 
    Height="50" />

C#

StoreData storeData = null;

public MainPage()
{
    storeData = new StoreData();

    //setting the ListView source to the sample data 
    ItemListView.ItemsSource = storeData.Collection;

    // making sure the first item is the selected item
    ItemListView.SelectedIndex = 0;           
}

void ItemListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
    ItemViewer iv = args.ItemContainer.ContentTemplateRoot as ItemViewer;

    if (args.InRecycleQueue == true)
    {
        iv.ClearData();
    }
    else if (args.Phase == 0)
    {
        iv.ShowTitle(args.Item as Item);

        // Register for async callback to visualize Title asynchronously
        args.RegisterUpdateCallback(ContainerContentChangingDelegate);
    }
    else if (args.Phase == 1)
    {
        iv.ShowDescription();
        args.RegisterUpdateCallback(ContainerContentChangingDelegate);
    }

    // For imporved performance, set Handled to true since app is visualizing the data item
    args.Handled = true;
}

private TypedEventHandler<ListViewBase, ContainerContentChangingEventArgs> ContainerContentChangingDelegate
{
    get
    {
        if (_delegate == null)
        {
            _delegate = new TypedEventHandler<ListViewBase, ContainerContentChangingEventArgs>                (ItemListView_ContainerContentChanging);
        }
            return _delegate;
    }
}

private TypedEventHandler<ListViewBase, ContainerContentChangingEventArgs> _delegate;

private void search_SuggestionsRequested(Object sender, SearchBoxSuggestionsRequestedEventArgs e)
{

    IEnumerable<Item> suggestionList = (IEnumerable<Item>)storeData.Collection.Cast<Item>();

    string queryText = e.QueryText;

    if (!string.IsNullOrEmpty(queryText))
    {

        Windows.ApplicationModel.Search.SearchSuggestionCollection suggestionCollection = e.Request.SearchSuggestionCollection;

        foreach (Item suggestedItem in suggestionList)
        {
            String suggestion = suggestedItem.Title;
            Debug.WriteLine(suggestion);

            if (suggestion.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
            {
                suggestionCollection.AppendQuerySuggestion(suggestion);

            }

            else
            {
                 //this is the line throwing the exception     
                 ItemListView.Items.RemoveAt(ItemListView.SelectedIndex); 
            }
        }
    }
}

我是 Windows 开发的新手。我们将不胜感激。

【问题讨论】:

    标签: c# xaml windows-8.1 win-universal-app


    【解决方案1】:

    这必须很快,因为我正要离开。简而言之,您需要两个集合来过滤数据,一个是原始的、未触及的集合,另一个是要显示的过滤集合。假设您有数据将名为 FilterTextstring 属性绑定到 UI(用户键入以过滤集合的属性)。

    您可以使用此string 来过滤使用LinQ 的集合,如下所示:

    if (FilterText == string.Empty) 
        FilteredCollection = new ObservableCollection<strging>(OriginalCollection);
    else FilteredCollection = new ObservableCollection<strging>(
        OriginalCollection.Where(s => s.StartsWith(FilterText)));
    

    将此代码放入一个方法并从FilterText setter 调用它,以便在键入每个字符后更新集合。当然,您需要将FilterText Binding 上的Binding.UpdateSourceTrigger 属性设置为PropertyChanged 才能使其按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-07
      • 2016-10-04
      • 2011-02-07
      • 2018-07-11
      • 1970-01-01
      相关资源
      最近更新 更多