Проблема с литьем |

У меня есть ObservableCollection UrlsList. У меня также есть флажок в моем приложении WPF, который изменяет элементы в списке, используя свойство IsChecked. Проблема, с которой я столкнулась, - это когда я пишу некоторые лямбда-выражения для фильтрации данных, которые я хочу, я не могу назначить их обратно в UrlsList. Он просто устанавливает мой список в null, который затем сбой приложения. Спасибо за вашу помощь.

ViewModel

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>;
}

Предупреждение Msg

Всего 2 ответа


Ваша проблема в том, что вы, по-видимому, используете Select вместо Where

Ниже приводится список IEnumerable<bool>

UrlsList.Select(url => url.ExistsInDb)

Кажется, что вы хотите на самом деле Where , что фильтрует список

UrlsList.Where(url => url.ExistsInDb);

Перечислимый метод.

Проецирует каждый элемент последовательности в новую форму.

Перечислимый метод.

Фильтрует последовательность значений на основе предиката.



Вы пытаетесь IEnumerable<T> обратно в ObservableCollection<T> . Это связано с ошибкой, потому что значение, возвращаемое LINQ yuery , не является наблюдаемой коллекцией.

Есть пара проблем с кодом:

  1. Вы используете Enumerable.Select когда вы должны использовать Enumerable.Where . Select проекты в список в список с разными значениями (это не то, что вы хотите), в то время как Where будет фильтровать ваш список ( это то, что вы хотите).
  2. Запрос LINQ должен быть реализован, например, с помощью Enumerable.ToList или Enumerable.ToArray . Результат Where is is not-materialized IEnumerable , выполнение которого отложено. Ваш ObservableCollection - полная коллекция.
  3. Вы не можете материализовать свой запрос LINQ с типом. Вы должны сами создать коллекцию.

Учитывая все эти проблемы, ваш код будет выглядеть следующим образом:

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 а затем пользовательский интерфейс будет автоматически изменяться вместе с ней.


Есть идеи?

10000