1. 程式人生 > >wpf mvvm datagrid資料過濾

wpf mvvm datagrid資料過濾

原文: 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}" >