Несколько фильтров на ICollectionView с несколькими проверками условий WPF
Этот вопрос задавался ранее в разных формах, но никто не отвечает на мой вопрос. Я прочитал этот форум и форум разработчиков Windows для информации, прежде чем опубликовать это. Я не могу понять, как выполнить эту задачу.
Я в своем уме.
У меня есть DataGrid, который связан с ICollectionView. Эти данные были получены с помощью хранимой процедуры, и DataGrid автоматически создается на основе столбцов в каждой таблице. Для справки, SP возвращает список объектов, каждый из которых содержит ряд элементов, таких как stock_symbol, stock_price, Date и т. Д.
Есть ряд фильтров, которые я хотел бы применить к этому представлению коллекции. Два комбо-бокса и два указателя даты, чтобы быть более конкретным. Каждый с флажком, чтобы указать, что они активны.
Каждый обработчик событий флажка хранит данные, которые были выбраны из выпадающего списка или средства выбора даты. Я пытаюсь сравнить, что находится в этих переменных, с каждым соответствующим членом списка объектов и отправить этот отфильтрованный список объектов обратно в DataGrid.
Это мой код:
private void FillDataGrid()
{
//Connect contains a simple stored procedure connection to SQL server
var Client = Connect();
DTOClass[] dTOs = Client.GetData();
SetDTOClass(dTOs);
MainGrid.ItemsSource = FilterView(dTOs);
}
Вот FilterView() (извиняюсь за длинные комментируемые разделы, я пытаюсь включить мои попытки в один прогон):
public ICollectionView /*List<DTOClass>*/ FilterView(DTOClass[] DTO)
{
if (_CollectionViewInternal == null)
{
//Assign collected DTO object to an ICollectionView
_CollectionViewInternal =
CollectionViewSource.GetDefaultView(DTO);
}
/*
ObservableCollection<DTOClass> DTOview = null;
if (DTOViewInternal == null)
{
int j = DTO.Length;
DTOview = new ObservableCollection<DTOClass>();
for(int i = 0; i < j; i++)
{
DTOview.Add(DTO[i]);
}
DTOViewInternal = DTOview;
}
*/
//Add a default sort description to the Date column
_CollectionViewInternal.SortDescriptions.Add(new SortDescription("Date", ListSortDirection.Ascending));
//assign our view to the maingrid (move this to later in the
//MainGrid.ItemsSource = _CollectionViewInternal;
if (MainGrid.ItemsSource != null)
{
/*List<Predicate<IEnumerable<DTOClass[]>>>*/ FilteredView = new List<Predicate<IEnumerable<DTOClass[]>>>();
//DateTime _zeroDay = new DateTime(1, 1, 1);
//DateTime _now = DateTime.Now;
FilteredView.Clear();
return FilteredView = _CollectionViewInternal.Where(Function(w) w.accountname.Contains(txtFilter.Text) _
Or w.firstname.Contains(txtFilter.Text) _
Or w.lastname.Contains(txtFilter.Text) _
Or w.isenabled.Contains(txtFilter.Text) _
Or w.description.Contains(txtFilter.Text) _
Or w.lastlogontimestamp.Contains(txtFilter.Text) _
Or w.whencreated.Contains(txtFilter.Text) _
Or w.whenchanged.Contains(txtFilter.Text) _
Or w.oulocation.Contains(txtFilter.Text) _
Or w.co.Contains(txtFilter.Text) _
Or w.l.Contains(txtFilter.Text) _
Or w.state.Contains(txtFilter.Text))
//if (yearsChosen > 0)
/* Stock, Maxadj, FromDate, ToDate */
/*
if (Stock_CheckBox.IsChecked != null)
{
FilteredView.Add(new Predicate<IEnumerable<DTOClass[]>>(x => x.Where(item => item. == Stock_ComboBoxText)));
}
if (letterChosen != "Any")
{
FilteredView.Add(new Predicate<IEnumerable<DTOClass[]>>(x => x.LastName.StartsWith(letterChosen)));
}
if (genderChosen != "Any")
{
FilteredView.Add(new Predicate<IEnumerable<DTOClass[]>>(x => x.Gender.Equals(genderChosen.Substring(0, 1))));
}
_CollectionViewInternal.Filter = dynamic_Filter;
RaisePropertyChanged("PeopleView");
// Bring the current person back into view in case it moved
if (CurrentPerson != null)
{
IEnumerable<DTOClass[]> current = CurrentPerson;
_CollectionViewInternal.MoveCurrentToFirst();
_CollectionViewInternal.MoveCurrentTo(current);
}
*/
/*
if (DTOview == null)
{
DTOview = DTOViewInternal;
} else
{
DTOViewInternal.
}
*/
//var collection = DTO;
//var symbol = collection.Where(item => item.Date == ).ToList();
//DTOview = new ObservableCollection<DTOClass>();
//IEnumerable<DTOClass> DTOview2;
//List<IEnumerable<DTOClass>> FilteredView = new List<IEnumerable<DTOClass>>();
/*
if (Stock_ComboBoxText != null)
{
//var collection = DTO;
var collection = DTO.Where(item => item.stock_symbol == Stock_ComboBoxText).Cast<DTOClass>().ToList();
//DTOview.Add(filtered.Cast<DTOClass>());
//FilteredView.Add(collection.Cast<DTOClass>());
FilteredView.Add(collection);
MainGrid.ItemsSource = FilteredView[0];
//FilteredView = filtered.Cast<DTOClass>();
}
if (Maxadj_ComboBoxText != 0)
{
var collection = DTO.Where(item => item.stock_price_adj_close == Maxadj_ComboBoxText).Cast<DTOClass>().ToList();
FilteredView.Add(collection);
MainGrid.ItemsSource = FilteredView[0];
//DTOview.Add(DTO.Where(item => item.stock_price_adj_close == ).ToList());
}
if (From_DatePickValue != null)
{
var collection = DTO.Where(item => item.Date >= From_DatePickValue).Cast<DTOClass>().ToList();
FilteredView.Add(collection);
MainGrid.ItemsSource = FilteredView[0];
}
if (To_DatePickValue != null)
{
var collection = DTO.Where(item => item.Date <= To_DatePickValue).Cast<DTOClass>().ToList();
FilteredView.Add(collection);
MainGrid.ItemsSource = FilteredView[0];
}
*/
//DTOview = DTOViewInternal;
//DTOview = null;
//DTOClass[] dto = GetDTOClass();
//ListCollectionView collectionView = new ListCollectionView(DTOViewInternal);
/*
collectionView.Filter = (e) =>
{
//int j = DTO.Length;
DTOClass[] dtofiltered = e as DTOClass[];
//for (int i = 0; i < j; i++)
//{
if ((Stock_ComboBoxText != null) && (DTOview[0][i].stock_symbol == Stock_ComboBoxText))
{
return true;
}
if ((Maxadj_ComboBoxText != 0) && (DTOview[0][i].stock_price_adj_close == Maxadj_ComboBoxText))
{
return true;
}
if ((From_DatePickValue != null) && (DTOview[0][i].Date >= From_DatePickValue))
{
return true;
}
if ((To_DatePickValue != null) && (DTOview[0][i].Date <= To_DatePickValue))
{
return true;
}
}
return true;
};
*/
//return collectionView.Cast<DTOClass>().ToList();
//return collectionView.Filter;
//return null;
//MainGrid.ItemsSource = null;
//MainGrid.ItemsSource = (CollectionView)CollectionViewSource.GetDefaultView(collectionView.ToString());
}
else
{
//MainGrid.ItemsSource = DTOview[0].ToList();
//MainGrid.ItemsSource = DTOview;
//return DTOview[0].ToList();
return _CollectionViewInternal;
}
return _CollectionViewInternal;
}
Я хочу фильтровать только по столбцу, если установлен соответствующий флажок. Это легко выбрать с одним фильтром, но больше, чем один, оказывается несложным.
Как видите, я пытался найти множество решений. Я попытался использовать ObservableCollection, я попытался отфильтровать список объектов напрямую, а затем добавить его в ICollectionView. Ничего не работает
Я пытался привить этот пример: Сложная фильтрация ICollectionView. Но я не могу сделать из этого головы или хвосты. Я до сих пор не понимаю предикаты, и я действительно не могу понять, как это работает.
Я знаю, что это неодобрительно задавать вопросы "дай код". Но если бы кто-то мог просто увидеть это и указать, что я здесь делаю неправильно, возможно, даже дать мне код, я был бы очень благодарен. Я потратил недели, пытаясь понять это, и у меня не хватило времени на это задание.
Если нет, то это круто, но, пожалуйста, воздержитесь от комментариев в этой теме. Не гордитесь тем, что отказываетесь от ответа, я обычно программист на C и только что закончил полноразмерный порт OSX-Windows для огромного плагина Adobe AfterFX. Поэтому мне не нужны грубые замечания или чепуха о том, чтобы прилагать больше усилий к обучению, я просто хочу закончить это задание и покончить с ним.
Спасибо всем заранее.
1 ответ
Код для дополнения вышеуказанного комментария:
List<Predicate<IEnumerable<DTOClass[]>>> FilteredView = null;
public ICollectionView FilterView(DTOClass[] DTO)
{
List<Predicate<IEnumerable<DTOClass[]>>>FilteredView = new
List<Predicate<IEnumerable<DTOClass[]>>>();
FilteredView.Clear();
if (Stock_CheckBox.IsChecked != null)
{
FilteredView.Add(new Predicate<IEnumerable<DTOClass[]>>(x => x.Where(item => item.stock_symbol == Stock_ComboBoxText)));
}
}
Я даже не могу заставить работать первый предикат. Видимо.stock_symbol не существует, и я не могу проиндексировать элемент. Я предполагаю, что мой реальный вопрос здесь - как мне получить доступ к члену stock_symbol?
Извиняюсь за то, что так долго добирался, я крайне лишен сна.
РЕДАКТИРОВАТЬ:
Тупые ошибки совершаются без сна.
List<Predicate<DTOClass>> FilteredView = new List<Predicate<DTOClass>>();
if (Stock_CheckBox.IsChecked != null)
{
for (int i = 0; i < DTO.Length; i++)
{
FilteredView.Add(new Predicate<DTOClass>(x => x.stock_symbol == _Stock_ComboBoxText));
//FilteredView.Add(new Predicate<DTOClass[]>>(x => x.stock_symbol == _Stock_ComboBoxText));
}
}