かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

手軽なスクリプト言語としてのF# その15「WPFしてみた」

さて、これまでで基本的にOOPチックな考えてF#のプログラムを書くときに必要そうなことは大体おさえてると思われます。ということで、一区切りの寄り道として簡単なWPFアプリケーションを組んでみようと思います。コードの解説はしません。簡単にコード内にコメントで何をしているか書いているのでそれを参照してください。

プロジェクトの設定

まず、F#のコンソールアプリケーションのプロジェクトを作成してプロジェクトのプロパティを開きます。コンソールアプリケーションという設定になっているので、これをWindowsアプリケーションに変更します。

そして、参照設定で以下のものを追加します。

  • PresentationCore
  • PresentationFramework
  • WindowsBase
  • UIAutomationTypes

レッツプログラミング

プロジェクトの設定が終わったら以下のようなコードを書きます。

// スクリプトで実行したときのための参照設定
// fsi このファイル名 で実行したときに有効になる
#if INTERACTIVE
#r "PresentationCore.dll"
#r "PresentationFramework.dll"
#r "WindowsBase.dll"
#endif

open System
open System.Windows
open System.Windows.Controls

// メインウィンドウ
type MainWindow() as this =
    inherit Window()
    
    // ウィンドウに置くコントロール
    let panel = StackPanel()
    let button = Button(Content = "Click")
    let text = TextBlock()

    do
        // 色々初期化するよ
        this.Title <- "F#"
        
        // イベントを追加!後方パイプ演算子がいい仕事してます
        button.Click.Add <| fun e ->
            text.Text <- DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")        
        
        // StackPanelへコントロールを追加。値はいらないのでignore関数で捨ててる
        panel.Children.Add button |> ignore
        panel.Children.Add text |> ignore
        
        // 最終的にパネルをコンテンツに追加
        this.Content <- panel


type App() as this =
    inherit Application()
    do
        // StartupイベントでMainWindowの表示
        this.Startup.Add <| fun e ->
            let w = MainWindow()
            w.Show()

// アプリを実行する関数
let main() =
    let app = App()
    app.Run() |> ignore

// STAThreadで動かしたい時はdoに属性つけるらしい
[<STAThread>]
do
    main()

初めて出てくるのはignore関数くらいだと思います。これは戻り値を捨てる関数です。戻り値がいらないけど、メソッドを呼びたいときにパイプ演算子でつないで呼び出したりします。
実行するとウィンドウが表示されて、ボタンを押すと画面に現在の時刻が表示されます。