目錄
WPF DataGrid 數據過濾
ICollectionView
使集合具有當前記錄管理、自定義排序、篩選和分組功能。
- 它的 SortDescriptions、GroupDescription 等屬性會影響視圖的結構,一般情況下會自動刷新。
- 也可以直接使用 Refresh 方法來命令視圖的刷新(內部實現一般為重建內部視圖模型集合)。
- 如果是批量操作,也可以使用 RefreshDefer 方法來抑制多次刷新,待多個更新操作后再統一刷新。
屬性
| CanFilter | 獲取一個值,該值指示此視圖是否支持通過 Filter 屬性進行篩選。 |
|---|---|
| CanGroup | 獲取一個值,該值指示此視圖是否支持通過 GroupDescriptions 屬性進行分組。 |
| CanSort | 獲取一個值,該值指示此視圖是否支持通過 SortDescriptions 屬性進行排序。 |
| Culture | 獲取或設置根據區域性而可能不同的視圖的任何操作(如排序)的區域性信息。 |
| CurrentItem | 獲取視圖中的當前項。 |
| CurrentPosition | 獲取視圖中 CurrentItem 的序號位置。 |
| Filter | 獲取或設置用於確定某個項是否適合包含在視圖中的回調。 |
| GroupDescriptions | 獲取 GroupDescription 對象的集合,這些對象描述集合中的項在視圖中的分組方式。 |
| Groups | 獲取頂級組。 |
| IsCurrentAfterLast | 獲取一個值,該值指示視圖的 CurrentItem 是否超出集合的末尾。 |
| IsCurrentBeforeFirst | 獲取一個值,該值指示視圖的 CurrentItem 是否超出集合的開頭。 |
| IsEmpty | 返回一個值,該值指示獲得的視圖是否為空。 |
| SortDescriptions | 獲取 SortDescription 對象的集合,這些對象描述集合中的項在視圖中的排序方式。 |
| SourceCollection | 返回基礎集合。 |
方法
| Contains(Object) | 返回一個值,該值指示給定項是否屬於此集合視圖。 |
|---|---|
| DeferRefresh() | 進入延遲循環,該循環可用於將更改合並到視圖並延遲自動刷新。 |
| MoveCurrentTo(Object) | 將指定項設置為視圖中的 CurrentItem。 |
| MoveCurrentToFirst() | 將視圖中的第一項設置為 CurrentItem。 |
| MoveCurrentToLast() | 將視圖中的最后一項設置為 CurrentItem。 |
| MoveCurrentToNext() | 將視圖中位於 CurrentItem 之后的項設置為 CurrentItem。 |
| MoveCurrentToPosition(Int32) | 將位於指定索引位置的項設置為視圖中的 CurrentItem。 |
| MoveCurrentToPrevious() | 將視圖中位於 CurrentItem 之前的項設置為 CurrentItem。 |
| Refresh() | 重新創建該視圖。 |
事件
| CurrentChanged | 在實現此接口時,在當前項改變之后引發此事件。 |
|---|---|
| CurrentChanging | 在實現此接口時,在改變當前項前引發此事件。 事件處理程序可以取消此事件。 |
如果在MVVM中不用ICollectonView的后果
如果我們不用ICollectionView,我們選中ListBox某一項,還必須跟SelectionChanged事件定義一個綁定方法來綁定Command,來處理事件(我們以MvvmLight的處理方式來處理Command),這里我們還要添加MvvmLight中的EventToCommand行為。代碼如下
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding SelectionChangedCommand, Mode=OneWay}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
如果在MVVM中使用ICollecionView
上面的問題就很簡單了,不需要添加SelectionChanged事件定義一個綁定方法來綁定Command,我們只需要使用ICollcetionView實例的CurrentItem就可以了,是不是簡單了很多呢!ICollectionView除了當前選中項,還有分頁、分組功能。可以用ListBox,Combox,DataGrid,DataPager等數據項控件.
簡單案例
針對過濾,其實官方提供了一個解決方案,就是利用ICollectionView。該接口包含了一個Refresh方法,同時包含一個filter屬性,該屬性是用來過濾的,使用的時候,后台數據這么寫:
public ICollectionView ViewSource { set; get; }
在ViewModel的構造方法里面這么寫:
ViewSource =
System.Windows.Data.CollectionViewSource.GetDefaultView(GlobalData.StatusList);
ViewSource.Filter = new Predicate<object>(OnFilterMovie);
bool OnFilterMovie(object item)
{
if (CurrentType == "all") return true;
else return (item as MovieModel).Type == CurrentType;
}
然后CurrentType屬性這么寫,當變更時,調用ViewSource的Refresh方法刷新一次數據
private string currentType = "all";
public string CurrentType
{
get => currentType;
set
{
if (currentType != value)
{
currentType = value;
ViewSource.Refresh();
}
}
}
而前端綁定還按照普通綁定的方法寫就可以了:
<DataGrid SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding ViewSource}">
