スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門 Windowsアプリケーション編 ListBox(2)

順番があっちこっちにとんでしまってますが、今回はListBoxの話題です。

ListBoxのイベントで一番よく利用されるのはSelectedValueChangedイベントで、これは選択している値が変更になったときに呼び出されます。
 
さて今回は次のようなアプリを作成してみたいと思います。 
 
813-1.jpg 
 
左上にラベルが一つとListBoxが3つ並んでいて、一つ目のリストボックスでは、List.existsかList.forallの選択。二つ目のリストボックスでは真か偽かを返す関数の選択、三つ目のリストボックスでは、対象とするリストを選びます。
そして、その組み合わせでの関数の値をラベルに表示するという訳です。
上の例では
List.forall (fun x -> x>0) [-2;0;2]が評価され、結果のFalseが表示されています。
 
プログラムの構造としては単純で単に、一つ目と二つ目のリストボックスに関数を、三つめのリストボックスにリストを収めておきSelectedValueChangedイベントが発生したときに、計算して結果を表示するだけです。
たで、関数をそのままListBoxに格納したのでは、デフォルトのToStringメソッドでは、どのような関数か分かるように表示できないので、クラスを定義して、このなかに関数と、表示用の文字列を収めるようにします。
List.forallとList.exsits用のクラスとしてListFuncs型を次のように定義します。
 
type ListFuncs (lFunc : (int -> bool) -> list<int> -> bool,desc :string) =
    member this.LFunc = lFunc
    override this.ToString() = desc 
 
List.forall等の第一引数となる関数用のクラスとしてInnerFuncs型を次のように定義します。
 
type InnerFuncs (iFunc : (int -> bool) ,desc :string) =
    member this.IFunc = iFunc
    override this.ToString() = desc 
 
あとはSelectedValueChangedが発火したときに、それぞれのリストボックスから、関数を取り出して、(キャストして、フィールドを抜き出す)適用すればよいということになります。
全コードは以下の通りになります。
 
open System
open System.Windows.Forms
open System.Drawing
 
 
type ListFuncs (lFunc : (int -> bool) -> list<int> -> bool,desc :string) =
    member this.LFunc = lFunc
    override this.ToString() = desc 
 
type InnerFuncs (iFunc : (int -> bool) ,desc :string) =
    member this.IFunc = iFunc
    override this.ToString() = desc 
 
//引数である、リストボックスのリスト内のリストボックスがすべて何らかの値を選択しているか。
let isAllListBoxSelected (lbes:list<ListBox>) =
    lbes
    |> List.forall(fun lb ->  lb.SelectedIndex >= 0)
 
//リストボックスにリスト内の項目をすべて追加する
let add2ListBox (lbx:ListBox) (lst:List<'a>) =
    List.iter (fun x -> lbx.Items.Add x |> ignore) lst
 
let mainForm = new Form(Width = 480, Height = 250, Text = "MyListBox Window")
mainForm.Show() |> ignore
 
let myListBox1 = new ListBox( Location = new Point(10,40))
let myListBox2 = new ListBox( Location = new Point(150,40),Width = 175)
let myListBox3 = new ListBox( Location = new Point(340,40))
let myListBoxes = [myListBox1;myListBox2;myListBox3]
 
[new ListFuncs(List.exists,"List.exists");
 new ListFuncs(List.forall,"List.forall")]
 |> add2ListBox myListBox1 
 
[new InnerFuncs((fun x -> x > 0),"(fun x -> x > 0)");
 new InnerFuncs((fun x -> x % 2 = 0),"(fun x -> x % 2 = 0)")]
 |> add2ListBox myListBox2 
 
[[1;2;3];[-1;2;3];[-2;0;2];[-3;-1]]
 |> add2ListBox myListBox3
 
let myLabel = new Label(Location = new Point (10,10),Text = "")
 
myListBoxes |>
 List.iter (fun c -> c.SelectedValueChanged.Add
                        (fun _ -> if isAllListBoxSelected myListBoxes then
                                    let lFun =(myListBox1.SelectedItem :?> ListFuncs).LFunc
                                    let iFun =(myListBox2.SelectedItem :?> InnerFuncs).IFunc
                                    let lArg =(myListBox3.SelectedItem :?> list<int>)
                                    //計算結果をラベルに表示
                                    myLabel.Text <- (lFun iFun lArg).ToString()
                            ))
 
[myListBox1;myListBox2;myListBox3]
 |> List.iter (fun x -> mainForm.Controls.Add (x) |> ignore)
 
mainForm.Controls.Add(myLabel)
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。