{"id":3236,"date":"2015-07-13T18:40:07","date_gmt":"2015-07-13T18:40:07","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=3236"},"modified":"2015-07-13T18:40:07","modified_gmt":"2015-07-13T18:40:07","slug":"f-mvvm-plumbing-code","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/f-mvvm-plumbing-code\/","title":{"rendered":"F# MVVM plumbing code"},"content":{"rendered":"<p>I&#8217;m trying to see how far I can go in implementing a WPF application purely in F# (and I don&#8217;t mean that third party or framework libraries must be F#, just my code). The  application isn&#8217;t going to be massive or probably very complex, I&#8217;m just interested in finding the &#8220;pain points&#8221; of using F# and WPF. <\/p>\n<p>In previous posts I&#8217;ve created the code to start-up an application and load the main window along with how I might assign a view model to the DataContext of the main window. <\/p>\n<p>I now want to take care of the usual mundane tasks such as binding to a view model, handling property change events on the INotifyPropertyChanged interface and implementing commands using the ICommand interface.<\/p>\n<p><strong>Handling property changes and INotifyPropertyChanged<\/strong><\/p>\n<p>In my C# WPF projects I use a extension methods that both assign values (if a property has changed) and raises PropertyChanged events using Expression objects as opposed to &#8220;magic strings&#8221;, i.e.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic string Name\r\n{\r\n   get { return name; }\r\n   set { this.RaiseAndSetIfChanged(x =&gt; x.Name, ref name, value); }\r\n}\r\n<\/pre>\n<p>I wanted to have something similar in F#. Instead of extension methods, I went the base class route<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype ViewModelBase() =\r\n    let propertyChanged = Event&lt;_, _&gt;()\r\n    interface INotifyPropertyChanged with\r\n        &#x5B;&lt;CLIEvent&gt;]\r\n        member this.PropertyChanged = propertyChanged.Publish\r\n\r\n    member private this.OnPropertyChanged p = propertyChanged.Trigger(this, PropertyChangedEventArgs(p))\r\n           \r\n    member this.RaisePropertyChanged (p : obj) =\r\n        match p with\r\n        | :? string as s -&gt; \r\n                this.OnPropertyChanged s\r\n        | :? Expr as e -&gt; \r\n                match propertyName e with\r\n                | Some(pi) -&gt; \r\n                    this.OnPropertyChanged pi\r\n                | None -&gt; ()\r\n        | :? (string array) as a -&gt;\r\n                a\r\n                |&gt; Array.iter (fun propertyName -&gt; this.RaisePropertyChanged propertyName) \r\n        | :? (Expr array) as a -&gt;\r\n                a\r\n                |&gt; Array.iter (fun propertyExpression -&gt; this.RaisePropertyChanged propertyExpression) \r\n        | null -&gt;\r\n                this.OnPropertyChanged null\r\n        | _ -&gt; ()\r\n\r\n    member this.RaiseAndSetIfChanged ((p : obj), (backingField : 'b byref), newValue) =\r\n        assert (p &lt;&gt; null)\r\n\r\n        match EqualityComparer.Default.Equals(backingField, newValue) with\r\n        | true -&gt; false\r\n        | false -&gt; \r\n            backingField &lt;- newValue\r\n            this.RaisePropertyChanged p\r\n            true\r\n\r\n<\/pre>\n<p>Where the propertyName functions is defined elsewhere as <\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet rec propertyName quotation =\r\n    match quotation with\r\n    | PropertyGet (_,propertyInfo,_) -&gt; Some(propertyInfo.Name)\r\n    | Lambda (_,expr) -&gt; propertyName expr\r\n    | _ -&gt; None\r\n<\/pre>\n<p><em>Note: This function is documented <a href=\"http:\/\/www.contactandcoil.com\/software\/dotnet\/getting-a-property-name-as-a-string-in-f\/\" target=\"_blank\">Getting a Property Name as a String in F#<\/a><\/em><\/p>\n<p>You&#8217;ll notice that whilst we can overload methods in an F# type, I&#8217;ve gone with pattern matching against types passed into the RaisePropertyChanged method. This just seemed tidier and allowed me to use the same function for passing a null as well (so binding on all properties should update).<\/p>\n<p>This view model base class allows me to raise a property against a &#8220;magic string&#8221;, against a Expr or against an array of either (useful when I wanted to force multiple readonly properties to update).<\/p>\n<p>The RaiseAndSetIfChanged function expects a non-null property <em>p<\/em> which can be a string or an Expr.<\/p>\n<p><em>There might be a better way to do this in F#, but this is what I&#8217;ve come up with thus far.<\/em><\/p>\n<p>So to use the above code in our view model we would write something like<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype MyViewModel() =\r\n    inherit ViewModelBase()\r\n\r\n    let mutable name = &quot;&quot;\r\n\r\n    member this.Name with get() = name and \r\n                                set(value) = \r\n                                    this.RaiseAndSetIfChanged (&lt;@ fun (v : MyViewModel) -&gt; v.Name @&gt;, &amp;name, value) |&gt; ignore\r\n<\/pre>\n<p>The use of the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dd233212.aspx\" target=\"_blank\">Code Quotations<\/a> in F# don&#8217;t look quite as good (or terse) as C# and I&#8217;m not sure if there&#8217;s a better way, but they&#8217;re still better than &#8220;magic strings&#8221;.<\/p>\n<p><strong>Commands<\/strong><\/p>\n<p>Next up, we need to handle ICommand. I want something akin to ActionCommand, so implemented<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype Command(execute, canExecute) =\r\n    let canExecuteChanged = Event&lt;_, _&gt;()\r\n    interface ICommand with\r\n        &#x5B;&lt;CLIEvent&gt;]\r\n        member this.CanExecuteChanged = canExecuteChanged.Publish\r\n        member this.CanExecute param = canExecute param\r\n        member this.Execute param = execute param\r\n\r\n    new(execute) =\r\n        Command(execute, (fun p -&gt; true))\r\n\r\n    member this.RaiseCanExecuteChanged p = canExecuteChanged.Trigger(this, EventArgs.Empty)\r\n<\/pre>\n<p>and in use with have <\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\ntype MyViewModel() =\r\n    inherit ViewModelBase()\r\n\r\n    let mutable name = &quot;&quot;\r\n\r\n    member this.Name with get() = name and \r\n                                set(value) = \r\n                                    this.RaiseAndSetIfChanged (&lt;@ fun (v : MyViewModel) -&gt; v.Name @&gt;, &amp;name, value) |&gt; ignore\r\n\r\n    member this.PressMe = Command(fun p -&gt; this.Name &lt;- &quot;Hello &quot; + this.Name)\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m trying to see how far I can go in implementing a WPF application purely in F# (and I don&#8217;t mean that third party or framework libraries must be F#, just my code). The application isn&#8217;t going to be massive or probably very complex, I&#8217;m just interested in finding the &#8220;pain points&#8221; of using F# [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6,13],"tags":[],"class_list":["post-3236","post","type-post","status-publish","format-standard","hentry","category-f","category-wpf"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/3236","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=3236"}],"version-history":[{"count":7,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/3236\/revisions"}],"predecessor-version":[{"id":3243,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/3236\/revisions\/3243"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=3236"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=3236"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=3236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}