【问题标题】:C# - Find items in ObservableCollectionC# - 在 ObservableCollection 中查找项目
【发布时间】:2015-01-03 06:44:00
【问题描述】:

我正在尝试为我使用 ObservableCollection 绑定到的 Listbox 添加一个“搜索” 功能,但我没有不知道我该怎么做。

对于我的 ObservableCollection

ObservableCollection<ItemProperties> ItemCollection { get; set; }
public class ItemProperties : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ItemProperties() { }

        private string m_ID;
        public string ID
        {
            get { return m_ID; }
            set
            {
                m_ID = value;
                OnPropertyChanged("ID");
            }
        }

        private string m_Title;
        public string Title
        {
            get { return m_Title; }
            set
            {
                m_Title = value;
                OnPropertyChanged("Title");
            }
        }

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(name));
        }
    }

我将我的项目加载到列表框

        string[] fileNames = isf.GetDirectoryNames("Files/*.*");
        ItemCollection = new ObservableCollection<ItemProperties>();
        foreach (var Directory in fileNames)
        {
            // code which reads and loads the text files to string which then is added to the Collection
        }
        ItemCollection.Add(new ItemProperties { ID = a_ID, Title = a_Title});
        IEnumerable<ItemProperties> query = ItemCollection.OrderBy(Dat => Dat.Title);
        listBox1.ItemsSource = query;

现在我有一个启用文本框的按钮。启用 TextBox 并在我输入时,listBox1 应该只显示我输入的内容。如果我输入的内容不存在,则列表框不应显示这些项目。例如:

我怎样才能做到这一点并拥有这样的功能?我希望它类似于 Windows Phone 应用搜索。

删除方法(使用上下文菜单):

 var contextMenuOpenedIndex = listBox1.Items.IndexOf((sender as MenuItem).DataContext);
 ItemCollection.RemoveAt(contextMenuOpenedIndex);

当我点击删除按钮时,它会删除另一个项目,保留我真正想要删除的项目。

【问题讨论】:

  • 在我的脑海中,TextBox 我认为有一个类似于“Changed”的事件,每次键入时都会触发。在那里,您可以按框中的内容过滤完整列表。这应该会在您键入时更改。

标签: c# windows-phone-8 filter listbox observablecollection


【解决方案1】:

考虑使用CollectionViewSource 作为您的数据源,而不是直接使用您的 ObservableCollection。您可以将此对象声明为 XAML 元素或在后面的代码中对其进行标注。每当您遇到适当的 UI 事件时刷新视图,例如您的搜索框失去焦点或按下某个键,以符合您所需的 UI 响应能力为准。

private CollectionViewSource MySource { get; set; }

private void PopulateView()
{
    string[] fileNames = isf.GetDirectoryNames("Files/*.*");
    ItemCollection = new ObservableCollection<ItemProperties>();
    foreach (var Directory in fileNames)
    {
        // code which reads and loads the text files to string which then is added to the Collection
    }
    ItemCollection.Add(new ItemProperties { ID = a_ID, Title = a_Title});

    // Create view
    MySource = new CollectionViewSource {
        Source = ItemCollection
    };

    // Add sorting support
    MySource.View.SortDescriptions.Add(new SortDescription("Title", ListSortDirection.Ascending));

    // Create a filter method
    MySource.View.Filter = obj => 
    {
        var item = obj as ItemProperties;

        // Predicate to determine if search box criteria met; change as needed
        return item.Title.Contains(txtMyFilter.Text);
    }

    // Initialize selected item to avoid SelectionChanged event
    MySource.View.MoveCurrentToFirst()

    // Set as ListBox source
    listBox1.ItemsSource = MySource.View;
}

// Bind to XAML TextBox element's KeyUp event or similar
private void OnFilterKeyUp(object sender, KeyEventArgs e)
{
    MySource.View.Refresh();

    // Include any other display logic here, such as possibly scrolling to top of ListBox
}

关于您的删除代码,我不鼓励您尝试排列索引。试试吧:

ItemCollection.Remove((sender as MenuItem).DataContext as ItemProperties);

【讨论】:

  • 为什么它给我一个:无法将类型“System.Windows.Data.CollectionViewSource”隐式转换为“System.Collections.IEnumerable”。 listBox1.ItemsSource = Mysource 上存在显式转换(您是否缺少演员表?)?
  • @F4z 抱歉,应该是listBox1.ItemsSource = MySource.View。我已经更新了答案以反映这一事实。该属性的类型为ICollectionView,它同时实现了IEnumerableINotifyCollectionChanged
  • 它过滤!这很好,但是我有两个问题。第一个问题是,当我搜索一个 quey 并显示它时,我无法删除该项目。另一个问题是,由于某种原因,当页面加载时,会触发 listBox1_SelectionChanged 事件。我已经稍微更新了答案,显示了我的删除方法。
  • @F4z 快速查看了您的删除。不要尝试匹配索引。通过引用删除该项目。有关示例,请参阅我的代码编辑。
  • 我遇到了一个异常:'System.Collections.ObjectModel.Collection.Remove(main.p_Menu.ItemProperties)' 的最佳重载方法匹配有一些无效参数and 参数 1:无法从 'object' 转换为 'main.p_Menu.ItemProperties'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多