{"id":465,"date":"2012-02-01T11:56:32","date_gmt":"2012-02-01T11:56:32","guid":{"rendered":"http:\/\/www.themissingdocs.net\/wordpress\/?p=465"},"modified":"2012-02-01T11:56:32","modified_gmt":"2012-02-01T11:56:32","slug":"bindinglist-does-not-scale","status":"publish","type":"post","link":"https:\/\/www.themissingdocs.net\/?p=465","title":{"rendered":"BindingList does not scale&#8230;"},"content":{"rendered":"<p>So I&#8217;ve been doing some UI work in the last 6 months or so &#8211; experimenting with MVVM and the like.\u00a0 Mostly with WPF, but also some win forms.<\/p>\n<p>Until the last few days I had managed to avoid working with BindingList, for one reason or another.\u00a0 Either because I was using ObservableCollection in WPF or because my lists were static, or they always updated in bulk.\u00a0 As part of my investigation into BindingList I found that it supports something which ObservableCollection does not. That is, cascade notification of changes to elements.\u00a0 So if an element type supports INotifyPropertyChanged, then BindingList will raise events when an element raises its PropertyChanged event, saying which element changed and more specifically which property on that element changed.\u00a0 Seems like a kind of nifty feature, at first glance&#8230;<\/p>\n<p>But the implementation does not scale, it is slow, it performs terribly with larger lists.\u00a0 If your element type supports INotifyPropertyChanged, every time one of those elements raises the property changed event the entire list is walked to work out the index in the list of the item which raised the event!\u00a0 I was in shock when I first realised this.\u00a0 You see BindingList is truly just a rather thin wrapper over Collection&lt;T&gt;, so there is no metadata associated with each entry, all of the binding of the element PropertyChanged event is directed to a single handler, and all it gets given is the source and the name of the changed property, so there is no way to include the NewIndex parameter in ListChangedEventArgs without doing a search.\u00a0 (By default this search even uses the default object comparator, so if you happen to have two different but sometimes equal objects in your list, enjoy the results&#8230;)<\/p>\n<p>Another side note &#8211; AddNew, the other feature which BindingList has which Collection&lt;T&gt; does not &#8211; also does not scale.\u00a0 It has to use IndexOf to find out where in the list the newly added item ended up\u00a0 in case it needs to cancel the add, because it supports auto sorting in derived types. (BindingList does not support auto sorting itself&#8230;)<\/p>\n<p>Morale of the story&#8230; don&#8217;t use BindingList for more than a hundred or so items which support INotifyPropertyChanged &#8211; write your own.\u00a0 If you do write your own, consider just not supporting the cascading modify events at all (even though you can do it efficiently if you have to).\u00a0 Item presentation should bind to the items, not to the list which holds them.\u00a0 But alas, not every control agrees&#8230;<\/p>\n<p>(PS &#8211; BindingSource internally creates a BindingList in many scenarios&#8230;)<\/p>\n<p>(PPS &#8211; Heh, I just realized this is immediately after my Contains rant, and is effectively an IndexOf rant, which I said I hadn&#8217;t seen misused much&#8230;)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So I&#8217;ve been doing some UI work in the last 6 months or so &#8211; experimenting with MVVM and the like.\u00a0 Mostly with WPF, but also some win forms. Until the last few days I had managed to avoid working with BindingList, for one reason or another.\u00a0 Either because I was using ObservableCollection in WPF &hellip; <a href=\"https:\/\/www.themissingdocs.net\/?p=465\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">BindingList does not scale&#8230;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-465","post","type-post","status-publish","format-standard","hentry","category-net-stuff"],"_links":{"self":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/posts\/465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=465"}],"version-history":[{"count":0,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/posts\/465\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}