かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

F#用MVVMライブラリ作成日記

今日は、DataAnnotationsによる入力値のエラー検証を追加しました。今の所以下のような変更履歴です。

! KinkumaFramework F# v0.1
F#でViewModelを記載する際の補助ライブラリです。

!! 2011/6/26 v0.1.2
* FsValidatableViewModelBaseクラス
** DataAnnotationsによる入力値の妥当性検証機能を追加
* FsViewModelクラス
** SetAndNotifyメソッドの名前をsetに変更
** GetOrCreateCommandメソッドの名前をcommandに変更

!! 2011/6/25 v0.1.1
* F#用FsViewModelBaseクラス
** F#向けViewModelの基本クラス
* InteractionRequest<T>クラスのRaiseAsyncメソッド
** 非同期ワークフロー内でRaiseメソッドを発行する

このライブラリを使ったViewModleクラスの記述は以下のようになります。

namespace KinkumaFramework.FSharp.HelloWorld.ViewModel

open System
open System.Windows
open System.ComponentModel.DataAnnotations
open Microsoft.Practices.Prism.Interactivity.InteractionRequest
open Microsoft.Practices.Prism.Commands
open Okazuki.MVVM.PrismSupport.Interactivity
open Okazuki.MVVM.PrismSupport.FSharp
open KinkumaFramework.FSharp.Model

/// MainWindow用のViewModel
type MainViewModel() =
    inherit FsValidatableViewModelBase()

    let mutable name = Unchecked.defaultof<string>

    let mutable selected = Unchecked.defaultof<string>

    let mutable alertCommand = Unchecked.defaultof<DelegateCommand>

    let alertRequest = InteractionRequest<ShowMessageBoxConfirmation>()

    /// 名前(必須入力項目)
    [<Required(ErrorMessage = "名前を入力してください")>]
    member x.Name
        with get() = name
        and set v = x.set(&name, v, <@ x.Name @>)

    /// 選択結果を表すメッセージ
    member x.Selected
        with get() = selected
        and set v = x.set(&selected, v, <@ x.Selected @>)

    /// Viewへ通知を行うためのInteractionRequest
    member x.AlertRequest = alertRequest

    /// ボタンが押された時のコマンド
    member x.AlertCommad = x.command(&alertCommand, x.AlertExecute, x.CanAlertExecute)

    /// コマンドの処理
    member private x.AlertExecute() =
        async {
            let message = greet x.Name
            let! result = x.AlertRequest.RaiseAsync(
                            ShowMessageBoxConfirmation(
                                Title = "確認", 
                                Content = greet x.Name, 
                                Button = Nullable<MessageBoxButton>(MessageBoxButton.OKCancel)))
            x.Selected <- match result.Confirmed with
                            | true -> "OKが押されました"
                            | false -> "Cancelが押されました"
        } |> Async.StartImmediate

    /// AlertCommandの実行可否判定
    member private x.CanAlertExecute() = not (x.HasErrors)

割と好みかも。