创建一个 TextBoxSearch 以从 ListView WPF 中过滤
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15473048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create a TextBoxSearch to filter from ListView WPF
提问by greg
I'm creating a application that allows a user to add some Employee details into EntityFrameworkmodel using WPF.
我正在创建一个应用程序,允许用户EntityFramework使用 WPF将一些员工详细信息添加到模型中。
So far, I have a ListViewto represent a list of employee names, and when you select the name of the employee, it selects that specific data in another ListView. I have accomplished this using a Predicateand a ICollectionSource.
到目前为止,我有一个ListView代表员工姓名列表,当您选择员工姓名时,它会选择另一个ListView. 我已经使用 aPredicate和 a完成了这项工作ICollectionSource。
But what I want to achieve now, is to have a so called search engine. So when a user types in an employees name in a TextBoxit filters the names of the employee names, depending on what is typed into the search box.
但我现在想要实现的,是拥有一个所谓的搜索引擎。因此,当用户在 aTextBox中输入员工姓名时,它会根据在搜索框中键入的内容过滤员工姓名。
I have used This Linkas a guide, but I am not too sure how to implement it within my own design; in the example they have used a Resourceand used an Array.
我已使用此链接作为指南,但我不太确定如何在我自己的设计中实现它;在示例中,他们使用了 aResource并使用了Array。
This is what I have tried instead, using a Predicate;
这是我尝试过的,使用Predicate;
private EmployeeListViewModel()
: base("")
{
EmployeeList = new ObservableCollection<EmployeeViewModel>(GetEmployees());
this._view = new ListCollectionView(this.employeeList);
}
private ListCollectionView _view;
public ICollectionView View
{
get { return this._view; }
}
private string _TextSearch;
public string TextSearch
{
get { return _TextSearch; }
set
{
_TextSearch = value;
OnPropertyChanged("TextSearch");
if (String.IsNullOrEmpty(value))
View.Filter = null;
else
View.Filter = new Predicate<object>(o => ((EmployeeViewModel)o).FirstName == value);
}
}
in my view;
在我看来;
<TextBox Height="23" Name="txtSearch" VerticalAlignment="Bottom" Margin="70,0,0,183" Width="100" Grid.Row="1"
Text="{Binding TextSearch, UpdateSourceTrigger=PropertyChanged}"/>
But what seems to happen is when I type something in, it throws this exception;
但似乎发生的是当我输入一些东西时,它会抛出这个异常;
Object reference not set to an instance of an object.
Object reference not set to an instance of an object.
So my question is, how can I implement this so it actually enables me to filter the list of names like in a searchbox?
所以我的问题是,我如何实现这一点,以便它实际上使我能够像在搜索框中一样过滤名称列表?
Any help would be grateful or guidance how to achieve this.
任何帮助将不胜感激或指导如何实现这一目标。
回答by WiiMaxx
Ok after creating a test Project i can't reproduce your exception
好的,创建测试项目后,我无法重现您的异常
here is my working code:
这是我的工作代码:
MainWindow.xaml
主窗口.xaml
<Window x:Class="gregory.bmclub.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBox Text="{Binding TextSearch,UpdateSourceTrigger=PropertyChanged}"/>
<ListView Height="380" HorizontalAlignment="Left" Name="lsNames" VerticalAlignment="Top" Width="170"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
SelectedItem="{Binding SelectedEmployee}"
ItemsSource="{Binding View}" Grid.RowSpan="2" Grid.Row="1">
<!--ItemsSource changed to "View"-->
<ListView.View>
<GridView>
<GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" Width="80" />
<GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}" Width="80" />
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</Window>
MainWindow.cs
主窗口.cs
using System.Windows;
namespace gregory.bmclub
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new EmployeeListViewModel();
}
}
}
EmployeeViewModel.cs
员工视图模型.cs
namespace gregory.bmclub
{
public class EmployeeViewModel
{
string firstname;
public string FirstName
{
get { return firstname; }
set { firstname = value; }
}
}
}
EmployeeListViewModel.cs
EmployeeListViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.ComponentModel;
namespace gregory.bmclub
{
class EmployeeListViewModel : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
public EmployeeListViewModel()//modified to public
{
EmployeeList = new ObservableCollection<EmployeeViewModel>(GetEmployees());
this._view = new ListCollectionView(this.employeeList);
}
#region nonModifiedCode
private ListCollectionView _employeeCol;
public ICollectionView EmployeeCollection
{
get { return this._employeeCol; }
}
private ObservableCollection<EmployeeViewModel> employeeList;
public ObservableCollection<EmployeeViewModel> EmployeeList
{
get { return employeeList; }
set
{
employeeList = value;
OnPropertyChanged("EmployeeList");
}
}
private ListCollectionView _view;
public ICollectionView View
{
get { return this._view; }
}
private string _TextSearch;
public string TextSearch
{
get { return _TextSearch; }
set
{
_TextSearch = value;
OnPropertyChanged("TextSearch");
if (String.IsNullOrEmpty(value))
View.Filter = null;
else
View.Filter = new Predicate<object>(o => ((EmployeeViewModel)o).FirstName == value);
}
}
#endregion
//created for testing
private List<EmployeeViewModel> GetEmployees()
{
var mylist = new List<EmployeeViewModel>();
mylist.Add(new EmployeeViewModel() { FirstName = "nummer1" });
mylist.Add(new EmployeeViewModel() { FirstName = "nummer2" });
return mylist;
}
}
}
回答by Sudani
i had the following code working with me but i had to ditch the Textsearch method and a pplied a different one i added view lines of code hopefully that make your code to work.
我有以下代码与我一起工作,但我不得不放弃 Textsearch 方法和一个不同的方法,我添加了代码视图行,希望可以使您的代码正常工作。
private EmployeeListViewModel()
: base("")
{
EmployeeList = new ObservableCollection<EmployeeViewModel>(GetEmployees());
this._view = new ListCollectionView(this.employeeList);
myEmployeeList = new CollectionViewSource();
myEmployeeList.Source = this.EscortList;
myEmployeeList.Filter += ApplyFilter;
}
internal CollectionViewSource employeeList { get; set; }
internal CollectionViewSource myEmployeeList { get; set; }
private ObservableCollection<EmployeeViewModel> employeeList;
public ObservableCollection<EmployeeViewModel> EmployeeList
{
get { return employeeList; }
set
{
employeeList = value;
OnPropertyChanged("EmployeeList");
}
}
private ListCollectionView _view;
// the collection below is the collection you will need to be your listview itemsource {Binding View}
public ICollectionView View
{
//you need to return your CollectionViewSource here
get { return myEmployeeList._view; }
}
// you need to use the following filtering methods as it did work for methods
private void OnFilterChanged()
{
myEmployeeList.View.Refresh();
}
private string filter;
public string Filter
{
get { return this.filter; }
set
{
this.filter = value;
OnFilterChanged();
}
}
void ApplyFilter(object sender, FilterEventArgs e)
{
EmployeeViewModel svm = (EmployeeViewModel)e.Item;
if (string.IsNullOrWhiteSpace(this.Filter) || this.Filter.Length == 0)
{
e.Accepted = true;
}
else
{
// you can change the property you want to search your model
e.Accepted = svm.Surname.Contains(Filter);
}
}
here is my Xaml code to bind to Listview
这是我要绑定到 Listview 的 Xaml 代码
<ListView Name="lsvEscort" HorizontalAlignment="Left" Height="297" ItemsSource="{Binding View}">
here is my text search filter binding path
这是我的文本搜索过滤器绑定路径
<TextBox x:Name="txtSearch" Grid.Column="1" Text="{Binding Path=Filter,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
hopefully this will resolve your issue
希望这将解决您的问题

