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.