2015-12-02 86 views
0

我有一個DataGrid,其中包含Jobs的數目。這些Jobs中的每一個都有一個與之關聯的員工,我想根據哪些員工在這些工作上進行篩選。所以我有四個CheckBoxes;基於複選框過濾ObservableCollection

<CheckBox x:Name="employeeARad" Content="EmployeeA" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Margin="7,0,0,5"/> 
<CheckBox x:Name="employeeBRad" Content="EmployeeD" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Margin="7,5,0,5"/> 
<CheckBox x:Name="employeeCRad" Content="EmployeeC" HorizontalAlignment="Left" Margin="7,5,0,5" VerticalAlignment="Top" FontSize="18"/> 
<CheckBox x:Name="employeeDRad" Content="EmployeeD" HorizontalAlignment="Left" Margin="7,5,0,5" VerticalAlignment="Top" FontSize="18"/> 

我檢索和我的數據庫填充數據的ObservableCollection。然後我使用:dataGrid.ItemsSource = _jobDataService.GetJobList();將此集合綁定到我的DataGrid。正如我之前所說的,每項工作的部分模型都與Employee相關聯。這是Job的模型;

class JobModel 
{ 
    public int CaseNumber { get; set; } 
    public string EmployeeName { get; set; } 
    public string CaseNotes { get; set; } 
    public DateTime DateCreated { get; set; } 
    public DateTime DateDeadline { get; set; } 
    public string CaseClient { get; set; } 
} 

我的問題真的是我如何可以篩選此集合,則勢必要基於的CheckBoxes的選擇DataGrid

+1

如果您需要過濾,最好使用ListCollectionView。 var lcv = new ListCollectionView(yourObservableCollection); yourDataGrid。的ItemsSource = LCV; – bamanow

回答

2

當您綁定到WPF中的集合時,將從幕後創建一個派生自ICollectionView的對象。該界面支持通過使用各種屬性對集合進行排序和過濾。

我通常所做的是將ObservableCollection<T>分配給專用字段,該字段包含所有數據。然後我有一個ICollectionView類型的相應公共財產,我可以使用任何排序或篩選條件。

以下是包含作業列表的簡單窗口的XAML,以及用於按員工姓名過濾列表的複選框。爲了簡單起見,我顯示的作業列表員工姓名:

<Window x:Class="StackOverflow.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <DockPanel Margin="10"> 
     <StackPanel x:Name="_employees" DockPanel.Dock="Top"> 
      <CheckBox Content="Fred" IsChecked="True" Click="OnCheckBoxClick" /> 
      <CheckBox Content="Wilma" IsChecked="True" Click="OnCheckBoxClick" /> 
      <CheckBox Content="Barney" IsChecked="True" Click="OnCheckBoxClick" /> 
      <CheckBox Content="Betty" IsChecked="True" Click="OnCheckBoxClick" /> 
     </StackPanel> 
     <ListBox ItemsSource="{Binding JobsCollectionView}" 
       DisplayMemberPath="EmployeeName" Margin="0,10,0,0" /> 
    </DockPanel> 
</Window> 

下面的代碼隱藏此窗口(我重用現有JobModel類,因此代碼ISN」這裏顯示T):

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 

namespace StackOverflow 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      _jobs = new ObservableCollection<JobModel> 
      { 
       new JobModel { EmployeeName = "Fred" }, 
       new JobModel { EmployeeName = "Wilma" }, 
       new JobModel { EmployeeName = "Fred" }, 
       new JobModel { EmployeeName = "Barney" }, 
       new JobModel { EmployeeName = "Betty" }, 
      }; 

      JobsCollectionView = CollectionViewSource.GetDefaultView(_jobs); 
      DataContext = this; 
     } 

     readonly ObservableCollection<JobModel> _jobs; 

     public ICollectionView JobsCollectionView { get; private set; } 

     void OnCheckBoxClick(object sender, RoutedEventArgs e) 
     { 
      var checkedEmployees = new HashSet<string>(); 
      foreach (CheckBox checkBox in _employees.Children) 
      { 
       if (checkBox.IsChecked == true) 
       { 
        checkedEmployees.Add((string) checkBox.Content); 
       } 
      } 

      JobsCollectionView.Filter = 
       job => checkedEmployees.Contains((job as JobModel).EmployeeName); 
     } 
    } 
} 

你可以看到私人_jobs領域持有的就業機會收集和公衆JobsCollectionView屬性,它提供了訪問ICollectionView實現(CollectionViewSource.GetDefaultView方法來獲得此)。

每個複選框控制具有點擊事件處理程序(它們都指向相同的方法),只需通過複選框迭代來構建其當前「檢查」員工名字的列表(checkedEmployees),然後設置集合視圖的Filter屬性以應用適當的過濾邏輯。基本上過濾器是一個從視圖中獲取項目的代理(在您的情況下爲JobModel對象),並返回一個布爾值,指示該特定對象是否應包含在視圖中。在這裏,我只是檢查來自作業的員工姓名是否包含在一組過濾的員工姓名中。

有一點需要注意的是ICollectionView排序和過濾的性能可能是非常大的列表的問題,在這種情況下,您可能需要通過從原始數據集構造一個全新的列表來排序/過濾。我會先嚐試收集視圖的方法,然後看看你如何繼續。

+0

感謝您的回答,這仍然適用於過濾'DataGrid'而不是'ListBox'? – CBreeze

+0

我沒有真正使用過'DataGrid',但我相信它就像'ListBox'一樣從'ItemsControl'派生,所以是的。 –

+0

我讓它工作正常,非常感謝。 – CBreeze