#c# #wpf #search #listbox
#c# #wpf #Поиск #listbox
Вопрос:
у меня есть listview, привязанный к наблюдаемой коллекции объектов. Здесь объектами являются «вопросы». Я хочу реализовать своего рода поисковую систему. В текстовом поле или что-то в этом роде. Но у меня есть 3 столбца. 1 из описания, 1 из краткого имени и 1 из типа вопроса. Вот код моего listview :
<ListView IsTextSearchEnabled="True" TextSearch.TextPath="Description" ScrollViewer.CanContentScroll="True" SelectedItem="{Binding Path=SelectedQuestionDragList, UpdateSourceTrigger=PropertyChanged,Mode=OneWayToSource}" dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="False" Margin="0,34,393,333" Background="#CDC5CBC5" ScrollViewer.VerticalScrollBarVisibility="Visible"
dd:DragDrop.DropHandler="{Binding}" Name="listbox1" Height="155" ItemsSource="{Binding AvailableQuestions}" SelectionChanged="listbox1_SelectionChanged">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Verkorte naam" Width="Auto" DisplayMemberBinding="{Binding Path=ShortName}" />
<GridViewColumn Header="Omschrijving" Width="Auto" DisplayMemberBinding="{Binding Path=Description}" />
<GridViewColumn Header="Type" Width="Auto" DisplayMemberBinding="{Binding Path=Type}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Я уже много чего перепробовал. Но я просто хочу сохранить одну простую вещь: текстовое поле, и если вы заполните там несколько букв, программа должна отфильтровать, где существует эта комбинация букв. Кто-нибудь, кто знает простое решение или пример?
Спасибо!
Ответ №1:
Пожалуйста, взгляните на CollectionViewSource
1) Создайте CollectionViewSource:
private readonly CollectionViewSource viewSource = new CollectionViewSource();
2) Укажите свой список в качестве источника:
viewSource.Source = list;
3) Установите свой viewsource в вашем ListView.
4) Когда вы это сделаете, вы можете использовать свойство Filter:
viewSource.Filter = FilterResults;
private bool FilterResults(object obj)
{
//match items here with your TextBox value.. obj is an item from the list
}
5) Наконец, поместите метод обновления ViewSource в текст, измененный в текстовом поле вашего фильтра:
void TextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
viewSource.Refresh();
}
Надеюсь, это поможет!
Комментарии:
1. но, я полагаю, все это есть в исходном коде? я пытаюсь поддерживать свой код в чистоте и работает с MVVM .. Есть идея о том, как это сделать?
2. @Ruben, ознакомьтесь с моим ответом о том, как это сделать на вашей виртуальной машине.
3. Работает любой способ.. ключевым моментом здесь является
CollectionViewSource
, либо путем его создания, либо с использованием значения по умолчанию.4. ДА. CollectionViewSource отлично подходит для фильтрации, сортировки и т.д., Без необходимости возиться с базовой коллекцией.
Ответ №2:
Вы также можете сделать это в своей ViewModel.
Сначала привяжите свое текстовое поле к свойству в вашей модели представления. Убедитесь, что в вашем XAML вы установили UpdateSourceTrigger
значение PropertyChanged
, чтобы получать обновления при каждом нажатии клавиши.
Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
В вашей viewmodel настройте свое свойство и свой CollectionView
:
ICollectionView ViewFilter;
private string _Filter;
public string Filter
{
get { return _Filter; }
set
{
_Filter = value;
RaisePropertyChanged("Filter");
}
}
В вашем конструкторе подключите представление и отслеживайте событие propertychanged:
ViewFilter = CollectionViewSource.GetDefaultView(AvailableQuestion);
ViewFilter.Filter = delegate(object item)
{
AvailableQuestion q = item as AvailableQuestion;
// Check the value and return true, if it should be in the list
// false if it should be exclucdd.
};
this.PropertyChanged = ((src, evt) =>
{
switch(evt.PropertyName)
{
case "Filter":
ProjectFilter.Refresh();
break;
}
Комментарии:
1. Итак, я должен поместить вторую часть (ViewFilter = CollectionViewSource. GetDefaultView(доступный вопрос);…..) в моем конструкторе моей viewmodel?
2. Да, это нужно поместить в конструктор.
Ответ №3:
Вот пользовательский элемент управления, который я создал, с помощью которого вы можете фильтровать любые ItemsControls, инкапсулирующие любой тип коллекции объектов любого типа. Это лучше, чем оставлять ваш код в чистоте: он заполняет XAML decalrative и совместим с «привязкой» 😉
Вы можете найти исходный код с примером (в следующих публикациях мы углубимся в компонент)
Преимущество заключается в том, что вам не нужно заботиться об управлении представлением коллекции и, таким образом, дополнять свою vewmodel проблемами пользовательского интерфейса (потому что вы должны смотреть правде в глаза: даже если это сделано в view model, фильтрация коллекции в основном касается пользовательского интерфейса, поэтому лучше не находиться в виртуальной машине). По крайней мере, внедрите эту логику в поведение 😉
Вот единственное, что вам нужно, чтобы иметь работающий фильтр в вашем listbox / listview :
<SmartSearch:SmartSearchRoot x:Name="ss2" Margin=" 10,0,10,0" >
<SmartSearch:SmartSearchScope DataControl="{Binding ElementName=YOUR_LISTVIEW_NAME}" UnderlyingType="{x:Type YOUR_NAMESPACE:YOUR_OBJECT_TYPE}">
<!-- The list of property on which you want to apply filter -->
<SmartSearch:PropertyFilter FieldName="YOUR_PROPERTY_ONE" />
<SmartSearch:PropertyFilter FieldName="YOUR_PROPERTY_TWO" MonitorPropertyChanged=""true" />
</SmartSearch:SmartSearchScope>
</SmartSearch:SmartSearchRoot>
Комментарии:
1. Я знаю, что это было довольно давно, но ссылка теперь возвращает сообщение 500. Есть ли вероятность, что это размещено где-то еще?