2015-01-02 2 views
0

Я пытаюсь добавить «Поиск» особенность моего Listbox, который я с помощью связанного приложения ObservableCollection, но я не знаю, как я могу сделать это.C# - Поиск элементов в ObservableCollection

Для моего 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)); 
     } 
    } 

загружаю свои товары в Listbox:

 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. Когда TextBox включен и по мере ввода, listBox1 должен показывать только то, что я набрал. Если то, что я набрал, не существует, Listbox не должен показывать элементы. например .:

enter image description here

Как я могу сделать это и есть такая возможность? Я хочу, чтобы это было похоже на поиск приложений Windows Phone.

Delete Метод (с помощью контекстного меню):

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

Когда я нажимаю на кнопку удаления, удаляет другой элемент, сохраняя тот, который я действительно хочу, чтобы удалить.

+0

Сверху моей головы «TextBox» Я думаю, что-то похожее на событие «Изменено», которое срабатывает при каждом вводе. Там вы можете отфильтровать полный список по тому, что находится в коробке. Это должно привести к его изменению по мере ввода. – Omada

ответ

1

Рассмотрите возможность использования CollectionViewSource в качестве источника данных, а не непосредственно используя ObservableCollection. Вы можете объявить этот объект как элемент XAML или его размер в коде. Обновляйте представление всякий раз, когда вы сталкиваетесь с соответствующим событием пользовательского интерфейса, например, в окне поиска, теряющем фокус или нажатой клавишей, в зависимости от того, что соответствует желаемой пользовательской интерфейсу.

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); 
+0

Почему это дает мне: Невозможно неявно преобразовать тип «System.Windows.Data.CollectionViewSource» в «System.Collections.IEnumerable». Явное преобразование существует (вы пропускаете листинг?) В listBox1.ItemsSource = Mysource? – Zer0

+0

@ F4z Извините, это должно было быть 'listBox1.ItemsSource = MySource.View'. Я обновил ответ, чтобы отразить этот факт. Свойство имеет тип ['ICollectionView'] (http://msdn.microsoft.com/en-us/library/system.componentmodel.icollectionview (v = vs.110) .aspx), который реализует как' IEnumerable', так и ' INotifyCollectionChanged'. – lsuarez

+0

Он фильтрует! это здорово, однако у меня две проблемы. Первая проблема заключается в том, что при поиске quey и его появлении я не могу удалить этот элемент. Другая проблема заключается в том, что по какой-то причине, когда страница загружается, запускается событие listBox1_SelectionChanged. Я немного обновил ответ, который показывает мой метод удаления. – Zer0

Смежные вопросы