У меня есть ObservableCollection UrlsList. У меня также есть флажок в моем приложении WPF, который изменяет элементы в списке, используя свойство IsChecked. Проблема, с которой я столкнулась, - это когда я пишу некоторые лямбда-выражения для фильтрации данных, которые я хочу, я не могу назначить их обратно в UrlsList. Он просто устанавливает мой список в null, который затем сбой приложения. Спасибо за вашу помощь.
public ObservableCollection<URLModel> UrlsList { get; set; } = new ObservableCollection<URLModel>();
public void CheckBoxOnClick()
{
if (URLModel.IsChecked)
UrlsList = UrlsList.Select(url => url.ExistsInDb) as ObservableCollection<URLModel>;
else
UrlsList = UrlsList.Select(n => n.ExistsInDb == false) as ObservableCollection<URLModel>;
}
Всего 2 ответа
Ваша проблема в том, что вы, по-видимому, используете Select
вместо Where
Ниже приводится список IEnumerable<bool>
UrlsList.Select(url => url.ExistsInDb)
Кажется, что вы хотите на самом деле Where
, что фильтрует список
UrlsList.Where(url => url.ExistsInDb);
Проецирует каждый элемент последовательности в новую форму.
Фильтрует последовательность значений на основе предиката.
Вы пытаетесь IEnumerable<T>
обратно в ObservableCollection<T>
. Это связано с ошибкой, потому что значение, возвращаемое LINQ yuery , не является наблюдаемой коллекцией.
Есть пара проблем с кодом:
Enumerable.Select
когда вы должны использовать Enumerable.Where
. Select
проекты в список в список с разными значениями (это не то, что вы хотите), в то время как Where
будет фильтровать ваш список ( это то, что вы хотите). Enumerable.ToList
или Enumerable.ToArray
. Результат Where
is is not-materialized IEnumerable
, выполнение которого отложено. Ваш ObservableCollection
- полная коллекция. Учитывая все эти проблемы, ваш код будет выглядеть следующим образом:
public void CheckBoxOnClick()
{
if (URLModel.IsChecked)
UrlsList = new ObservableCollection<URLModel>(UrlsList.Where(url => url.ExistsInDb));
else
UrlsList = new ObservableCollection<URLModel>(UrlsList.Where(url => !url.ExistsInDb));
}
Однако более тонкая ошибка в этом коде заключается в том, что при проверке, а затем снимите флажок, ваш список URL будет пустым, потому что вы сначала выбираете только отмеченные элементы в списке, а затем выбираете неконтролируемые элементы из этого списка. Поскольку вы отфильтровали список уже для отмеченных элементов, ваш второй выбор не даст результата. Вам нужно будет сохранить исходный список в другом месте и выбрать оттуда:
public void CheckBoxOnClick()
{
if (URLModel.IsChecked)
UrlsList = new ObservableCollection<URLModel>(allUrls.Where(url => url.ExistsInDb));
else
UrlsList = new ObservableCollection<URLModel>(allUrls.Where(url => !url.ExistsInDb));
}
Другая проблема заключается в том, что, если вы не измените список в другом месте, вам не понадобится ObservableCollection
, поскольку вы переназначаете список, когда этот флажок изменится. Вы можете либо использовать простой List<T>
либо массив, либо - и для этого на самом деле предназначена привязка данных - вы изменяете содержимое базы данных ObservableCollection
а затем пользовательский интерфейс будет автоматически изменяться вместе с ней.