在WPF中过滤ListView中的集合

时间:2013-03-11 09:15:48

标签: wpf entity-framework listview mvvm

我正在创建一个WPF应用程序,允许用户使用Entity Framework,CRUD操作和MVVM输入有关其Employee的一些详细信息。

到目前为止,我有两个ListViews。一个包含员工姓名列表(listview1),另一个列表(listview2)列出他们的详细信息,如出生日期,地址等。下面的图片将为您提供我正在创建的内容的更好的图片;

ListView

当我从listbox1中选择一个特定名称时,我使用CollectionViewSoruce使我能够在listview2上过滤结果。到目前为止,我能够实现这一目标,但是当我添加员工或删除时,它会引发异常;

 An unhandled exception of type 'System.StackOverflowException' occurred in *.UI.exe

以下是可能有用的代码段

视图模型:

    private EmployeeListViewModel()
        : base("")
    {
        EmployeeList = new ObservableCollection<EmployeeViewModel>(GetEmployees());
        this._employeeCol = new ListCollectionView(this.employeeList); 
    }

    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 EmployeeViewModel selectedEmployee = null;
    public EmployeeViewModel SelectedEmployee
    {
        get
        {
            return selectedEmployee;
        }
        set
        {
            selectedEmployee = value;
            OnPropertyChanged("SelectedEmployee");
            EmployeeCollection.Filter = new Predicate<object>(o => SelectedEmployee != null && o != null && ((EmployeeViewModel)o).EmployeeID == SelectedEmployee.EmployeeID);
        }
    }

    internal ObservableCollection<EmployeeViewModel> GetEmployees()
    {
        if (employeeList == null)
            employeeList = new ObservableCollection<EmployeeViewModel>();
        employeeList.Clear();

        foreach (DataObjects.Employee i in new EmployeeRepository().GetAllEmployees())
        {
            EmployeeViewModel c = new EmployeeViewModel(i);
            employeeList.Add(c);
        }
        return employeeList;
    }

ListView2 - EmployeeListView;

            <ListView Name="lsvEmpoyeeList" Height="170" Width="700"
                  ScrollViewer.VerticalScrollBarVisibility="Visible" 
                  ScrollViewer.HorizontalScrollBarVisibility="Visible" 
                  HorizontalAlignment="Center"
                  IsSynchronizedWithCurrentItem="True"
                  ItemsSource="{Binding EmployeeCollection}"
                  SelectedItem="{Binding SelectedEmployee}">
                    <ListView.View>
                      <GridView>
                        <GridViewColumn Header="Position" DisplayMemberBinding="{Binding Position}" Width="100" />
                        <GridViewColumn Header="DateOfBirth" DisplayMemberBinding="{Binding DateOfBirth, StringFormat={}\{0:dd/MM/yyyy\}}" Width="100" />
                     </GridView>
                    </ListView.View>
                </ListView>

ListView1 - EmployeeSetUpView;

            <ListView Height="380" HorizontalAlignment="Left" Name="lsNames" VerticalAlignment="Top" Width="170" 
             ScrollViewer.VerticalScrollBarVisibility="Visible" 
             ScrollViewer.HorizontalScrollBarVisibility="Visible" 
             SelectedItem="{Binding SelectedEmployee}" 
             ItemsSource="{Binding EmployeeList}" Grid.RowSpan="2" Grid.Row="1">

        <ListView.View>
            <GridView>
                <GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" Width="80" />
                <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}" Width="80" />
            </GridView>
        </ListView.View>
    </ListView>
   <ContentControl Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center"
                    Content="{Binding}" ContentTemplate="{StaticResource EmployeeListView}" />

如您所见,我已将过滤器放在setaccessor内。我将它放在构造函数中,但似乎发生的是ListView2上没有出现任何细节。

此外,如果我从listview2中选择一行而不是从listview1中选择一行,它也会生成StackOverFlowException,我不确定为什么。

任何帮助将不胜感激或建议。此外,抱歉这个大问题!

1 个答案:

答案 0 :(得分:3)

我不认为用户界面知道EmployeeCollection已更改

尝试在应用过滤器后在PropertyChanged setter中为EmployeeCollection添加SelectedEmployee个事件。

public EmployeeViewModel SelectedEmployee
{
    get { return selectedEmployee;}
    set
    {
        selectedEmployee = value;
        OnPropertyChanged("SelectedEmployee");
        EmployeeCollection.Filter = new Predicate<object>(o => SelectedEmployee != null && o != null && ((EmployeeViewModel)o).EmployeeID == SelectedEmployee.EmployeeID);

        // EmployeeCollection view has changed, Notify UI
        OnPropertyChanged("EmployeeCollection");
    }
}

至于StackOverflowException我认为这是由于ListViewTwoWay都有SelectedEmployee绑定这一事实造成的,所以当一个ListView1更改SelectedItem时会导致ListView2更新其选定的项目,更新ListView1等,等等。

尝试在ListView2

上为SelectedEmployee设置OneWay的绑定
  

SelectedItem =“{Binding SelectedEmployee,Mode = OneWay}”&gt;