我的UI中有TextBlock
绑定到属性的.Count()
扩展名。我想在属性中添加LINQ过滤,但是当我这样做时会破坏绑定。
这样可以毫无问题地更新UI:
public IEnumerable<Worker> WorkersTest
{
get
{
return DataManager.Data.Workers;
}
}
添加LINQ过滤后,WorkersTest
不会更新TextBlock
,但MessageBox会确认该属性正在被修改。但是,在初始化数据时,值会正确显示:
public IEnumerable<Worker> WorkersTest
{
get
{
return DataManager.Data.Workers.Where(w => w.Gender == Gender.Male);
}
}
有没有办法在不破坏绑定的情况下保持LINQ过滤?
更新:我需要澄清的一件事是DataManager.Data.Workers
是ObservableCollection
。
据我所知,任何LINQ操作都会破坏绑定,但AsEnumerable()
除外,它没有任何效果。
另外,回应Andres的回答,Count()
不是问题所在。如果我将此属性绑定到DataGrid
,我会得到相同的结果。使用LINQ,它不会更新。没有LINQ,它确实如此。是否有任何形式的解决方法,最好是不涉及ICollectionView
或其他任何性质的解决方案?
更新:有人知道Where
之类的LINQ扩展是否会在使用时返回新对象?我无法在网上找到任何此类文档。但是,如果是这种情况,则可能是问题所在。
更新:我插入了一个断点,并找到了一些有用的有趣信息:
没有LINQ:
使用LINQ:
也许这可以揭示真实情况,并希望让我更接近解决方案。
假设CollectionChanged
和PropertyChanged
为空是问题的根源,我是否正确?如果是这样,我该怎么做才能解决这个问题?
答案 0 :(得分:1)
您的问题源于不了解可观察的集合。 DataManager.Data.Workers
是ObservableCollection
或类似的东西。这意味着,它会在添加/删除项目时引发事件。然后,用户界面可以收听这些事件并进行适当更新。
LINQ对可观察集合一无所知。它只是一次读取数据并将其转换为新的集合。因此,使用LINQ进行过滤是行不通的。或者至少没有某种黑客攻击。
肯定有一些方法,例如Filtering an ObservableCollection?或Sorts and filters on ObservableCollection。但没有什么比简单的LINQ就这么容易了。或者也许Reactive Extensions可以帮到你。但我从未使用它,所以我不知道设置过滤可观察集合有多容易。
答案 1 :(得分:0)
尝试在Where子句的末尾添加.ToList()。
return DataManager.Data.Workers.Where(w => w.Gender == Gender.Male).ToList();
不允许绑定到方法,因此可能发生的是绑定到Count属性而不是方法。 List包含Count属性,而IEnumerable则不包含。