У меня большой объем данных в ObservableCollection, который привязан к DataGrid через слой ICollectionView следующим образом:
public ICollectionView ProductsCollectionView
{
get { return CollectionViewSource.GetDefaultView(Products); }
set { NotifyPropertyChanged("ProductsCollectionView"); refreshCollection(); }
}
Я хочу разрешить пользователям фильтровать эти данные с помощью строки поиска, эта часть работает а также:
ProductsCollectionView.Filter += new Predicate<object>(filterProduct);
Я также хочу добавить функцию разбиения на страницы для повышения производительности моего приложения, но я не могу понять, как объединить обе эти функции. Я попытался добавить в эту коллекцию дополнительный фильтр, который обрабатывал бы нумерацию страниц следующим образом:
ProductsCollectionView.Filter += new Predicate<object>(filterPages);
, но он дает неожиданные результаты при применении второго фильтра.
Я также пытался привязать к Вместо этого ObservableCollection и повторное инициализация его с помощью выражения LINQ каждый раз, когда происходит фильтрация, но я не могу соответственно обновить UI:
public ObservableCollection<ProductModel> Products
{
get
{
return products;
}
set
{
if(products != value)
{
products = value;
NotifyPropertyChanged("Products");
}
}
}
public ProductViewModel()
{
Products = db.GetProducts.Where(filterProduct).Skip(Start).Take(ItemCount).ToList();
}
Я пытался сделать то же самое на получателе ICollectionView.
У меня есть также попытался объединить оба фильтра в один и применить его к ICollectionView, это сработало, но производительность стала еще хуже:
public bool filterProduct(object obj)
{
var data = obj as ProductModel;
bool isAdded = false;
bool toReturn = false;
//SearchString filtering
if (!string.IsNullOrEmpty(searchString))
{
isAdded = data.Name.ToString().Contains(searchString)
}
else
{
isAdded = true;
}
//Beginning of pagination
if (CounterProducts == Products.Count)
{
CounterProducts = 0; //Counts how many products have been filtered
CounterAdded = 0; //Counts how many products passed the string filtering
}
CounterProducts++;
//Check result of searchString filtering
if (isAdded)
{
CounterAdded++;
}
//Determine right current page
int workingPage = 1;
if (previousSearchString == SearchString)
{
workingPage = CurrentPage;
}
//Pagination
if (CounterAdded > ItemsPerPage * (workingPage - 1) && CounterAdded <= (ItemsPerPage * workingPage) && isAdded)
{
toReturn = true;
}
//Last item
if (CounterProducts == Products.Count)
{
previousSearchString = SearchString;
if (CounterAdded % ItemsPerPage > 0)
{
TotalPages = (CounterAdded / ItemsPerPage) + 1;
}
else
{
TotalPages = CounterAdded / ItemsPerPage;
}
}
return toReturn;
}
Мне также нужно обновить объекты в коллекции во время выполнения , поэтому IEnumerable растворы могут не подходить здесь лучше (или я могу ошибаться?).
Я пробовал и другие способы, но я думаю, что этот вопрос уже достаточно длинный. Теперь я ищу любой совет или хороший подход для достижения как фильтрации по строке, так и нумерации страниц для сбора связанных данных. Любой вклад высоко ценится. Спасибо за ваше внимание.