Home > Blockchain >  Generic FilterClass<T> - within the class a List<predicate>(T) shall be set up, how with
Generic FilterClass<T> - within the class a List<predicate>(T) shall be set up, how with

Time:07-08

I've built a complex filter for my ICollection within my ViewModel. Now I need a similar filterfunction for a different collection and datagrid. So I guess it would suck big times if I was going to duplicate and adjust my code.

So I was going for a reusable solution.

Simple Code:

public class FilterForGrid<T>
    {
        public T UiModel { get; set; }
        private List<Predicate<T>> criteria = new List<Predicate<T>>();

        public FilterForGrid() {
           // var result = typeof(T).GetProperties().ToList();
        }

        private bool dynamicFilter(object obj) {
            T uiModel = (T)obj;
            bool isIn = true;
            if (criteria.Count() == 0)
                return isIn;
            isIn = criteria.TrueForAll(x => x(uiModel));
            return isIn;
        }

        public void ClearFilter() {
            criteria.Clear();
        }

        public void AddFilterArgument(string argument, string property) {
           // criteria.Add(new Predicate<T>(x => x.))
        }

        public void FireFilter(ICollectionView toBeFilteredCollection) {
            toBeFilteredCollection.Filter = dynamicFilter;
            toBeFilteredCollection.Refresh();
        }

    }

Have a look at the method "AddFilterArgument" --> I simply want to pass the name of the property and the value over which the data shall be filtered:

public void AddFilterArgument(string argument, string property) {
            criteria.Add(new Predicate<T>(x => x.property == argument))
        }

But because of type inteference the property can't be found this way.

Is my attemp possible or do I have to look in another direction? If its possible please give me a clue.

CodePudding user response:

Well, finally it was a much easier than expected:

Example for one of the methods

 public void AddFilterPredicate(string argument, string property, OperatorsForFIlter operators) {
        Predicate<T> predicate;

        if (!String.IsNullOrEmpty(argument)) { 
            switch (operators) {
                case OperatorsForFIlter.equal:
                    predicate = new Predicate<T>(x => x.GetType().GetProperty(property).GetValue(x, null).ToString() == argument);
                    break;
                case OperatorsForFIlter.contains:
                    predicate = new Predicate<T>(x => x.GetType().GetProperty(property).GetValue(x, null).ToString().Contains(argument));
                    break;
                default:
                    predicate = null;
                    break;
            }
        } else { predicate = new Predicate<T>(x => x.GetType().GetProperty(property).GetValue(x, null).ToString().Contains(argument)); }
        InsertIntoCriteriaCatalogue(property, predicate);
    }

This line here was exactly what I was asking for:

new Predicate<T>(x => x.GetType().GetProperty(property).GetValue(x, null).ToString().Contains(argument));

I was looking for a way to pass a name of a property as parameter and the value of the property through which the list should be filtered.

Now I can use the dynamic generic filter for all my data in every grid.

  • Related