使用Command过滤ObservableCollection

时间:2017-09-20 15:48:27

标签: c# wpf data-binding datagrid observablecollection

这是我的ViewModel

这绑定到我的datagrid并加载我的所有数据我遇到的问题是我已经将一个单选按钮绑定到一个命令,当它被选中时我希望它“过滤”我的FullItemList只显示空行在我的数据网格中。

    public class ResidentViewModel
{
    public ResidentViewModel()
    {
        AllRooms();
    }
    public ObservableCollection<Res_details> FullItemList { get; set; }

    private void AllRooms()
    {
        var items = new ObservableCollection<Res_details>();
        using (var db = new Access5687DB())
        {
            var q =
                from c in db.Residents
                select c;
            foreach (var c in q)
            {
                items.Add(new Res_details()
                {
                    ID = c.Room,
                    Name = c.Firstname,
                    LastName = c.Lastname,
                    Birthday = c.Birthday,
                    Arrival = c.Admission,
                });
            }
            FullItemList = items;
        }
    }

    private ICommand filter_Empty;
    public ICommand Filter_Empty
    {
        get { if (filter_Empty == null) filter_Empty = new FilterObs(); return filter_Empty; }
        set { filter_Empty = value; }
    }

    private class FilterObs : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            if ((string)parameter == "B")
                return
                    true;
            if ((string)parameter != "B")
                return
                    false;
            else
                return
                    false;
        }

        public void Execute(object parameter)
        {
              #Something needs to go here.
        }
    }
}

2 个答案:

答案 0 :(得分:1)

将ObservableCollection包装在CollectionViewSource中,并将其绑定到DataGrid。 CollectionViewSource有一个Filter回调。如果要更改过滤器,请调用CollectionViewSource.View.Refresh()。

答案 1 :(得分:1)

我同意SledgeHammer,使用ICollectionView是最好的解决方案。 要在filter命令中获取视图模型,需要将viewModel引用传递给命令,或者只传递delegate,如下所示(伪代码)

public class ResidentViewModel
{
    public ResidentViewModel()
    {
        FullItemList = CollectionViewSource.GetDefaultView(_itemList);
        Load();
    }

    private ObservableCollection<Res_details> _itemList { get; set; }
    public ICollectionView FullItemList { get; private set; }

    private void Load()
    {
        var items = new ObservableCollection<Res_details>();
        using (var db = new Access5687DB())
        {
            var q =
                from c in db.Residents
                select c;
            foreach (var c in q)
            {
                items.Add(new Res_details()
                {
                    ID = c.Room,
                    Name = c.Firstname,
                    LastName = c.Lastname,
                    Birthday = c.Birthday,
                    Arrival = c.Admission,
                });
            }
            _fullItemList = items;
        }
    }

    /*Apply filter to the collection view*/
    private void ShowEmptyLinesOnly(object parameter)
    {
        /*logic based on your parameter here*/


        FullItemList.Filter = FilterEmptyLine;//<-- set filter to collection view
        FullItemList.Refresh();
    }

    private bool FilterEmptyLine(object o)
    {
        var item = o as Res_details;
        if (item == null) return false;

        /*
         * decide if item is 'empty' and return true in case item is empty;
         */
    }

    private ICommand filter_Empty;
    public ICommand Filter_Empty
    {
        get { if (filter_Empty == null) filter_Empty = new FilterObs(ShowEmptyLinesOnly); return filter_Empty; }
        set { filter_Empty = value; }
    }

    private class FilterObs : ICommand
    {
        public event EventHandler CanExecuteChanged;
        private readonly Action<object> _filterAction;

        public FilterObs(Action<object> filterAction)
        {
            _filterAction = filterAction;
        }

        public bool CanExecute(object parameter)
        {
            if ((string)parameter == "B")
                return
                    true;
            if ((string)parameter != "B")
                return
                    false;
            else
                return
                    false;
        }

        public void Execute(object parameter)
        {
            _filterAction.Invoke(parameter);
        }
    }
}