wpf mvvm datagrid資料過濾
datagrid資料過濾,你可以通過設定RowStyle屬性,通過將Visibility繫結到ViewModel層的屬性來控制是否可見,比如:
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource DataGridRowVisibilityConverter}">
<Binding ElementName="dataGrid" Path="DataContext.CurrentType"/>
<Binding Path="Type"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
這裡我利用DataGridRowVisibilityConverter這個轉換器,當CurrentType=“all”時所有的都顯示,當CurrentType不是all時,要求datagrid資料來源裡面某個資料的Type值和CurrentType一致,才顯示。
但是這樣做有一個問題,就是當行的可見性變更後,資料並不會重刷,datagrid的row索引還是老的,需要手動重新整理,但是我們是mvvm模式,沒法手動重新整理datagrid的資料。我暫時還沒找到解決這個問題的方法。
針對過濾,其實官方提供了一個解決方案,就是利用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}" >