投放问题|我正在尝试返回类似的类型

时间:2018-11-12 10:02:45

标签: c# oop lambda

我有一个ObservableCollection UrlsList。我的WPF应用程序中也有一个复选框,该复选框使用IsChecked属性修改列表中的项目。我遇到的问题是,当我编写一些lambda表达式来过滤我想要的数据时,我无法将其分配回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>;
}

Warning Msg

2 个答案:

答案 0 :(得分:6)

您的问题是您似乎在使用Select而不是Where

以下内容产生一个列表IEnumerable<bool>

UrlsList.Select(url => url.ExistsInDb)

您实际上想要的是Where,它可以过滤列表

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

Enumerable.Select Method

  

将序列的每个元素投影为新形式。

Enumerable.Where Method

  

根据谓词过滤一系列值。


答案 1 :(得分:1)

您正在尝试将IEnumerable<T>投射回ObservableCollection<T>。那肯定会失败,因为LINQ yuery 返回的值不是可观察的集合。

您的代码有两个问题:

  1. 您应在使用Enumerable.Select时使用Enumerable.WhereSelect将列表投影到具有不同值(不是您想要的值)的列表,而Where将过滤您的列表(您想要的是 )。 / li>
  2. 必须使用例如Enumerable.ToListEnumerable.ToArray来实现LINQ查询。 Where的结果是未实现的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的内容,然后UI会随之自动更改。