読者です 読者をやめる 読者になる 読者になる

WPFにおけるMVVM --- F#コード版

F# MVVM WPF

前回下記記事にて紹介しましたC#版のMVVMを、F#化したものを掲載いたします。
WPFにおけるMVVM - 何でもプログラミング

実際には、冗長すぎる、mutableが頻発する、といった理由でこのままの記述方法を使うことはありません。

ただ単にC#をF#に書き直したらどうなるかの参考用の掲載となります。

F#でWPFを利用する方法は下記の記事を参照してください。
F#でWPF --- ウィンドウ表示 - 何でもプログラミング

Xaml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="MainWindow" Height="100" Width="215">
    <Grid>
        <Button Content="-" Command="{Binding Decrement}" HorizontalAlignment="Left" Margin="46,23,0,0" VerticalAlignment="Top" Width="25"/>
        <TextBlock Text="{Binding Count}" HorizontalAlignment="Left" Margin="97,25,0,0" TextWrapping="Wrap" VerticalAlignment="Top"/>
        <Button Content="+" Command="{Binding Increment}" HorizontalAlignment="Left" Margin="132,23,0,0" VerticalAlignment="Top" Width="25"/>
    </Grid>
</Window>

F#

open System
open System.ComponentModel
open System.Windows
open System.Windows.Input

let createCommand f = 
    let canExecuteChanged = Event<_, _>()
    { new ICommand with
        [<CLIEvent>]
        member this.CanExecuteChanged = canExecuteChanged.Publish
        member this.CanExecute _ = true
        member this.Execute _ = f() }

type ViewModel() as this =
    let propertyChanged = Event<_, _>()
    let mutable count = 0
    let updateCount x = 
        count <- x
        propertyChanged.Trigger(this, PropertyChangedEventArgs("Count"))
    let increment = createCommand (fun () -> count + 1 |> updateCount) 
    let decrement = createCommand (fun () -> count - 1 |> updateCount)

    member this.Count = count
    member this.Increment = increment
    member this.Decrement = decrement
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member this.PropertyChanged = propertyChanged.Publish

[<STAThread>]
[<EntryPoint>]
let main argv = 
    let window = Application.LoadComponent(Uri("MainWindow.xaml", UriKind.Relative)) :?> Window

    window.DataContext <- ViewModel()

    Application().Run(window) |> ignore    
    0