本文介绍了WPF:动态过滤dataGrid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的WPF Window 中,我有一个 DataGrid 控件,其 ItemsSource 绑定到了项目的ObservableCollection(比如说一个简单的对象,带有几个属性):

In my WPF Window I have a DataGrid control, with its ItemsSource bound to an ObservableCollection of items (let's say a simple object with a couple properties):

XAML: (为简洁起见,删除了一些xmlns内容)

<Window>
    <Window.Resources>
        <CollectionViewSource x:Key="MyViewSource"
                              Source="{Binding MyItemList}"
                              Filter="MyItemList_Filter"/>
    </Window.Resources>

    <Window.DataContext>
        <!-- Some Ioc stuff -->
    </Window.DataContext>

    <StackPanel>
        <TextBox Text="{Binding TextFilter}" />
        <DataGrid Grid.Row="1" x:Name="dataGrid"
            ItemsSource="{Binding Source={StaticResource MyViewSource}}"
            SelectionUnit="FullRow"
            SelectionMode="Extended"
            CanUserAddRows="False"
            CanUserDeleteRows="False"
            HeadersVisibility="Column" />
    </StackPanel>
</Window>

ViewModel(cs):

public class ViewModel : ViewModelBase // From Galasoft MVVM Light toolkit
{

    #region TextFilter Property
    public const string TextFilterPropertyName = "TextFilter";

    private string _TextFilter;

    public string TextFilter
    {
        get
        {
            return _TextFilter;
        }

        set
        {
            if (_TextFilter == value)
            {
                return;
            }

            _TextFilter = value;

            RaisePropertyChanged(TextFilterPropertyName);
        }
    }
    #endregion // TextFilter Property

    #region MyItemList Property
    public const string MyItemListPropertyName = "MyItemList";

    private ObservableCollection<Item> _MyItemList;

    public ObservableCollection<Item> MyItemList
    {
        get
        {
            return _MyItemList;
        }

        set
        {
            if (_MyItemList == value)
            {
                return;
            }

            _MyItemList = value;

            RaisePropertyChanged(MyItemListPropertyName);
        }
    }
    #endregion // MyItemList Property


}

Filter方法,来自 Window后面的代码:

Filter method, from Window's code behind:

private void MyItemList_Filter(object sender, FilterEventArgs e)
{
    var vm = (ViewModel)this.DataContext;
    var item = (Item)e.Item;
    // ...Simplified...
    e.Accepted = item.PropertyToCheck.Contains(vm.TextFilter);
}

仅在填充 MyItemList 时应用过滤:如何在实时" 上调用 MyItemList_Filter (并相应地显示/隐藏DataGrid项)TextFilter 更改了吗?

Filtering is applied only when filling MyItemList: how can I make the MyItemList_Filter be called (and DataGrid items be shown/hidden accordingly) on "live" TextFilter change?

任何帮助将不胜感激

推荐答案

您可以(应该)将过滤逻辑移至视图模型,例如:

You could (should) move the filtering logic to the view model, e.g.:

public class ViewModel : ViewModelBase
{
    public const string TextFilterPropertyName = "TextFilter";

    private string _TextFilter;
    public string TextFilter
    {
        get
        {
            return _TextFilter;
        }
        set
        {
            if (_TextFilter == value)
                return;
            _TextFilter = value;
            RaisePropertyChanged(TextFilterPropertyName);
            Filter();
        }
    }

    public const string MyItemListPropertyName = "MyItemList";

    private ObservableCollection<Item> _MyItemList;
    public ObservableCollection<Item> MyItemList
    {
        get
        {
            return _MyItemList;
        }
        set
        {
            if (_MyItemList == value)
                return;

            _MyItemList = value;
            RaisePropertyChanged(MyItemListPropertyName);
        }
    }

    private ObservableCollection<Item> _filtered;
    public ObservableCollection<Item> FilteredList
    {
        get
        {
            return _filtered;
        }
        set
        {
            if (_filtered == value)
                return;

            _filtered = value;
            RaisePropertyChanged("FilteredList");
        }
    }

    private void Filter()
    {
        _filtered.Clear();
        foreach(var item in _MyItemList)
        {
            if (item.PropertyToCheck.Contains(TextFilter))
                _filtered.Add(item);
        }
    }
}

这就是它的归属.然后,您无需使用CollectionViewSource:

That's where it belongs. Then you don't need to the CollectionViewSource:

<DataGrid Grid.Row="1" x:Name="dataGrid" ItemsSource="{Binding FilteredList}" ... />

这篇关于WPF:动态过滤dataGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 19:08