【问题标题】:Filtering ObservableCollection using Command使用命令过滤 ObservableCollection
【发布时间】:2018-03-01 18:42:27
【问题描述】:

这是我的ViewModel

这绑定到我的数据网格并加载我的所有数据我遇到的问题是我已经将一个单选按钮绑定到一个命令,当它被选中时,我希望它“过滤”我的 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.
        }
    }
}

【问题讨论】:

    标签: c# wpf data-binding datagrid observablecollection


    【解决方案1】:

    我同意 SledgeHammer,在这里使用 ICollectionView 是最好的解决方案。 要在 filter 命令中访问您的视图模型,您需要将 viewModel 引用传递给您的命令,或者您可以只传递委托,如下所示(伪代码)

    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);
            }
        }
    }
    

    【讨论】:

    • 感谢您提供的示例代码,它让我走上了正确的道路。接受为答案。
    【解决方案2】:

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

    【讨论】:

    • 抱歉,我没有尝试使用 IcollectionView。我现在会调查一下,我在使用命令时遇到问题,我无法访问它之外的任何内容。
    猜你喜欢
    • 2015-07-12
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 2011-07-04
    • 1970-01-01
    相关资源
    最近更新 更多