{"id":79,"date":"2018-10-03T06:56:11","date_gmt":"2018-10-03T06:56:11","guid":{"rendered":"https:\/\/engy.us\/blog\/?p=79"},"modified":"2018-10-03T06:56:11","modified_gmt":"2018-10-03T06:56:11","slug":"wpf-databinding-using-dynamicdata","status":"publish","type":"post","link":"https:\/\/engy.us\/blog\/2018\/10\/03\/wpf-databinding-using-dynamicdata\/","title":{"rendered":"WPF Databinding using DynamicData"},"content":{"rendered":"<p>My project is MVVM and I had been using ReactiveList&lt;T&gt; as my go-to observable collection for viewmodel properties. But ReactiveUI <a href=\"https:\/\/reactiveui.net\/blog\/2018\/08\/deprecated-reactive-list\">deprecated ReactiveList in 8.6.1<\/a>. So I needed to get on to the new recommended library: <a href=\"https:\/\/github.com\/RolandPheasant\/DynamicData\">DynamicData<\/a>.<\/p>\n<p>But there is no direct drop-in replacement you can do like ObservableCollection&lt;T&gt; &lt;-&gt; ReactiveList&lt;T&gt;. I grabbed the NuGet package, dropped in SourceList&lt;T&gt;, but that doesn&#8217;t work. SourceList&lt;T&gt; does not implement INotifyCollectionChanged, which is what WPF looks for when binding to ListView, GridView, ItemsControl, etc. So how do we bind to this thing? After some fruitless searches I dug through the source code unit tests and found the answer. Add this to the viewmodel class:<\/p>\n<pre>private readonly SourceList&lt;string&gt; myList = new SourceList&lt;string&gt;();\r\npublic IObservableCollection&lt;string&gt; MyListBindable { get; } = new ObservableCollectionExtended&lt;string&gt;();\r\n<\/pre>\n<p>And this to its constructor:<\/p>\n<pre>this.myList.Connect().Bind(this.MyListBindable).Subscribe();\r\n<\/pre>\n<p>It&#8217;s a two-stage affair. The SourceList&lt;T&gt; is where all the operations happen. Adds, clears, deletes and all that. But you don&#8217;t directly observe the source list. To do that, you need to call Connect() to get an IObservable&lt;IChangeSet&lt;T&gt;&gt; . If you follow this observable you can see everything that&#8217;s changed about the collection by looking at the change sets.<\/p>\n<p>But you still need to do one more thing: get it in a format that the WPF UI can bind to, that is an object that implements INotifyCollectionChanged. ObservableCollectionExtended is DynamicData&#8217;s implementation of that. The Bind() call &#8220;slaves&#8221; it to the SourceList. Any changes made in the SourceList are now reflected in the ObservableCollectionExtended. A final call to Subscribe() activates it. Now since we&#8217;re exposing it as a property, we can bind our UI to it:<\/p>\n<pre>&lt;ItemsControl\r\n\tItemsSource=\"{Binding MyListBindable}\"\r\n\t...\r\n<\/pre>\n<p>The important thing here is to remember that this property is here ONLY so the UI can bind to it. That&#8217;s why I&#8217;ve named it Bindable: so I&#8217;ll realize I&#8217;m doing something wrong if I try to modify it directly.<\/p>\n<p>The ObservableCollectionExtended property also allows you to get batches to avoid update churn from making individual edits to the collection. When you call Edit() on the SourceList&lt;T&gt;:<\/p>\n<pre>this.myList.Edit(innerList =&gt;\r\n{\r\n\tinnerList.Clear();\r\n\tforeach (string name in names)\r\n\t{\r\n\t\tinnerList.Add(name);\r\n\t}\r\n});\r\n<\/pre>\n<p>It will batch up all the changes made into one event under INotifyCollectionChanged, meaning the UI only needs to react once.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My project is MVVM and I had been using ReactiveList&lt;T&gt; as my go-to observable collection for viewmodel properties. But ReactiveUI deprecated ReactiveList in 8.6.1. So I needed to get on to the new recommended library: DynamicData. But there is no direct drop-in replacement you can do like ObservableCollection&lt;T&gt; &lt;-&gt; ReactiveList&lt;T&gt;. I grabbed the NuGet package, &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/engy.us\/blog\/2018\/10\/03\/wpf-databinding-using-dynamicdata\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;WPF Databinding using DynamicData&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[1],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pahBcK-1h","jetpack-related-posts":[{"id":43,"url":"https:\/\/engy.us\/blog\/2010\/03\/08\/saving-window-size-and-location-in-wpf-and-winforms\/","url_meta":{"origin":79,"position":0},"title":"Saving window size and location in WPF and WinForms","date":"March 8, 2010","format":false,"excerpt":"A common user interface tweak is to save the size and location of a window and restore that state when the program starts up again. That way, the users don\u2019t need to re-do their work of resizing and moving the windows to where they want them. However I\u2019ve found that\u2026","rel":"","context":"With 21 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":88,"url":"https:\/\/engy.us\/blog\/2018\/10\/20\/dark-theme-in-wpf\/","url_meta":{"origin":79,"position":1},"title":"Dark Theme in WPF","date":"October 20, 2018","format":false,"excerpt":"In a recent Windows 10 update a toggle switch was added to allow the user to specify that they wanted \"Dark\" themes in apps: I decided to add support for this to VidCoder. But no updates to WPF were made to make this easy. WPF does having theming support where\u2026","rel":"","context":"With 5 comments","img":{"alt_text":"","src":"https:\/\/i2.wp.com\/engy.us\/blog\/wp-content\/uploads\/2018\/10\/VidCoderDarkExample.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":120,"url":"https:\/\/engy.us\/blog\/2020\/01\/01\/implementing-a-custom-window-title-bar-in-wpf\/","url_meta":{"origin":79,"position":2},"title":"Implementing a Custom Window Title Bar in WPF","date":"January 1, 2020","format":false,"excerpt":"There are several good reasons for wanting custom window chrome in WPF, such as fitting in additional UI or implementing a Dark theme. However the actual implementation is kind of tricky, since it is now your job to provide a bunch of features that you used to get for free.\u2026","rel":"","context":"With 12 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":82,"url":"https:\/\/engy.us\/blog\/2018\/10\/04\/item-change-tracking-in-dynamicdata\/","url_meta":{"origin":79,"position":3},"title":"Item change tracking in DynamicData","date":"October 4, 2018","format":false,"excerpt":"Since ReactiveUI's ReactiveList<T> has recently been deprecated, I've been moving to DynamicData. One feature I used from ReactiveList was item change tracking. It might look something like this: var myList = new ReactiveList<MyClass>(); myList.ChangeTrackingEnabled = true; myList.ItemChanged .Where(x => x.PropertyName == nameof(MyClass.SomeProperty)) .Select(x => x.Sender) .Subscribe(myObject => { \/\/ Do\u2026","rel":"","context":"With 5 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":146,"url":"https:\/\/engy.us\/blog\/2021\/02\/28\/installing-net-5-runtime-automatically-with-inno-setup\/","url_meta":{"origin":79,"position":4},"title":"Installing .NET 5 Runtime Automatically with Inno Setup","date":"February 28, 2021","format":false,"excerpt":"In this guide I will walk through how to get the .NET 5 runtime to download and install on-the-fly in an Inno Setup installer. It works in 3 steps: Detect if the desired .NET runtime is installedDownload the .NET Runtime bootstrap installer with Inno Download PluginRun the bootstrap installer in\u2026","rel":"","context":"With 2 comments","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/engy.us\/blog\/wp-content\/uploads\/2021\/02\/image.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":165,"url":"https:\/\/engy.us\/blog\/2021\/10\/03\/efficient-svg-icons-in-web-components-with-webpack-and-svgo\/","url_meta":{"origin":79,"position":5},"title":"Efficient SVG icons in Web Components with Webpack and SVGO","date":"October 3, 2021","format":false,"excerpt":"So many ways to load them There are a lot of different ways to show an SVG on a webpage: <img>, <embed>, <object>, <iframe>, <canvas> and <svg> among them. I think for any halfway modern browser there are really only two serious contenders here. Referencing an SVG file: <img src=\"image.svg\"\u2026","rel":"","context":"Similar post","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/posts\/79"}],"collection":[{"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/comments?post=79"}],"version-history":[{"count":2,"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/posts\/79\/revisions"}],"predecessor-version":[{"id":81,"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/posts\/79\/revisions\/81"}],"wp:attachment":[{"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/media?parent=79"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/categories?post=79"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/engy.us\/blog\/wp-json\/wp\/v2\/tags?post=79"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}