开发者

bind linq expression

I have a ListView and ObservableCollection in my wpf application. I want to bind linq expression to ListView:

lv_Results.DataContext = store.Where(x => x.PR > 5).ToList();
tempStore = new M1Store()
                            {
                                SiteName = siteName,
                                Date = date,
               开发者_StackOverflow社区                 url = IndexedPage,
                                TCY = YandexTCY.GetYandexTCY(IndexedPage),
                                PR = Pagerank.GetPR(IndexedPage)
                            };
            store.Add(tempStore);

But when i add new elements to store collection, lv_Results doesnt updates. How can i update ListView?


Your problem is that you want the "Where" condition to be evaluated continuously on all items added to the "store" collection. The built-in LINQ "Where" operator is not designed to do that. Rather, when it is enumerated by the ListView it scans your collection exactly once then ignores it from then on.

Check out Continuous LINQ. It is designed to do exactly what you are looking for, and can be used almost as a drop-in replacement for standard LINQ queries.

Limitations of the built-in LINQ implementation

The built-in LINQ extension methods have a fundamental limitation in that the collections they produce don't support INotifyPropertyChanged. So no matter how much the underlying data changes, the client will never receive notification that the collection has changed and hence will never refresh its display of the data.

User jrista points out in the comments that the built-in LINQ methods do actually produce up-to-date data if re-enumerated. While true, this has no practical effect. No WinForms or WPF control contains code to periodically re-enumerate its data source. The reasons for not doing so are, of course, obvious: It would be incredibly wasteful. If you re-enumerate 10 times per second and it takes 10ms to re-enumerate and scan for changes you will use up 10% of your CPU for just one control!


Put your LINQ results into an ObservableCollection. WPF and Silverlight databinding require that collections raise change notifications, and ObservableCollection does that for you. Otherwise you'd have to implement it yourself, which is more of a pain and completely unnecessary.


The results from the LINQ expression are being fed into a new List(of T) which does not raise PropertyChanged or CollectionChanged events.

The easiest way to make it work is to retrieve the results you want, then populate an ObservableCollection(of T) with the results you want to display. As that ObservableCollection gets added to, the new items will appear in the ListView.


Add a .ToList() to your code, LINQ evaluates lazy, so it brings results only when needed, .ToList() is a greedy operator and forces an evaluation.

[edit]

Sorry, missunterstood your first version of the question :)

Here's my solution:

ObservableCollection<M1Store> l = store.Where(x => x.PR > 5);
lv_Results.DataContext = l;

Thats simply all, in all following steps, change the Observable collection l:

List<M1Store> otherList = GetFromAnywhere();
otherList.ForEach(e => l.Add(e));

Here the internals of the Observable Collection will Update the listView in the UI.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜