创建一个TextBoxSearch以从ListView WPF中过滤

gre*_*reg 2 c# wpf listview mvvm

我正在创建一个应用程序,允许用户EntityFramework使用WPF 将一些Employee详细信息添加到模型中.

到目前为止,我有一个ListView代表员工姓名列表,当您选择员工的名称时,它会选择另一个员工的特定数据ListView.我用a Predicate和a 完成了这个ICollectionSource.

但我现在想要实现的是拥有一个所谓的搜索引擎.因此,当用户在其中键入员工姓名时,TextBox它会过滤员工姓名的名称,具体取决于在搜索框中键入的内容.

我使用This Link作为指南,但我不太确定如何在我自己的设计中实现它; 在示例中,他们使用了a Resource并使用过Array.

这是我尝试过的,使用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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在我看来;

<TextBox Height="23" Name="txtSearch" VerticalAlignment="Bottom" Margin="70,0,0,183" Width="100" Grid.Row="1"
          Text="{Binding TextSearch, UpdateSourceTrigger=PropertyChanged}"/>
Run Code Online (Sandbox Code Playgroud)

但似乎发生的事情是当我输入内容时,它会抛出此异常;

Object reference not set to an instance of an object.

所以我的问题是,如何实现这一点,所以它实际上使我能够过滤搜索框中的名称列表?

任何帮助将是感激或指导如何实现这一目标.

Wii*_*axx 7

创建测试项目后确定我无法重现您的异常

这是我的工作代码:

MainWindow.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>
Run Code Online (Sandbox Code Playgroud)

MainWindow.cs

using System.Windows;

namespace gregory.bmclub
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new EmployeeListViewModel();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

EmployeeViewModel.cs

namespace gregory.bmclub
{
    public class EmployeeViewModel
    {
        string firstname;

        public string FirstName
        {
            get { return firstname; }
            set { firstname = value; }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)