スポンサーサイト

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

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

今回も前回に引き続きListViewの紹介です。
まずWindows FormとListView型のインスタンスを準備しておきます。
 
>open System
open System.Windows.Forms
open System.Drawing
 
let mainForm = new Form(Width = 450, Height = 200, Text = "MyListView Window")
mainForm.Show() |> ignore
let myListView = new ListView(Location = new Point(30,80),Width = 400)
mainForm.Controls.Add(myListView);;
 
さて前回はitem毎に文字列を一つ表示していましたが、今回は下図のようなListViewの表現方法を紹介します。 

816-1.jpg  
 
このような表記形態にするためにまず必要なのは、表示モードの設定です。次のようにViewプロパティをView.Detailsと設定します。
 
> myListView.View <- View.Details;;
 
次に必要なのは「列見出し」の設定です。これはColumnHeaderクラスのインスタンスを生成してこれをListViewのColumns.Addメソッドを使用して追加します。
 
> [new ColumnHeader(Text = "Col01",Width = 100);(*表示文字Col01で幅100の「列見出し」*)
new ColumnHeader(Text = "Col02",Width = 90);
new ColumnHeader(Text = "Col03",Width = 120)]
|> List.iter (fun col -> myListView.Columns.Add col |> ignore);;
val it : unit = ()
 
これで以下の状態になります。(これで3列は表示可能となりました。)

816-2.jpg 
 
ColumnHeader型を少し調べておきます。
 
> let colums0 = (myListView.Columns.Item 0);;//1列目のColumnsオブジェクト
val colums0 : ColumnHeader = ColumnHeader: Text: Col01
 
> colums0;;
val it : ColumnHeader =
  ColumnHeader: Text: Col01
    {Container = null;
     DisplayIndex = 0;
     ImageIndex = -1;
     ImageKey = "";
     ImageList = null;
     Index = 0;
     ListView = System.Windows.Forms.ListView, Items.Count: 0;
     Name = "";
     Site = null;
     Tag = null;
     Text = "Col01" TextAlign = Left;
     Width = 80;}
 
 
さて次はitem(項目)の追加です。
次のように初期化します。(前回は一つの文字列をコンストラクタに渡しましたが、今回は文字列の配列(string [] 型の値を渡します。)
 
> let myLVItem01 = new ListViewItem([|"item01col01";"item01col02";"item01col03"|]);;
val myLVItem01 : ListViewItem = ListViewItem: {item01col01}
 
myLVItem01を少し調べてみます。
> myLVItem01;;
val it : ListViewItem =
  ListViewItem: {item01col01}
    {BackColor = Color [Window];
        略
      SubItems = seq
                  [ListViewSubItem: {item01col01};
                   ListViewSubItem: {item01col02};
                   ListViewSubItem: {item01col03}];
        略
     Text = "item01col01";
        略
     UseItemStyleForSubItems = true;}
 
というようになっていて、Textには一番最初の文字列、SubItemsという部分に配列の各要素がListViewSubItem型の値に変換されて収められています。(ListViewItemのTextと、SubItemsの0番目の要素のTextは同じ文字列を指しています。(片方を変えるともう一方も変わります。)
 
それではmyLVItem01をmyListViewに追加します。
> myListView.Items.Add(myLVItem01) |> ignore;;
 
これで以下の状態になります。
 
816-3.jpg 
 
この場合表示列数は3でしたが、SubItemsの個数が、それより少ないかったり多かったりした場合はどう表示されるか調べてみます。
 
> let myLVItem02 = new ListViewItem([|"item02col01";"item02col02"|])//2個の場合
myListView.Items.Add(myLVItem02) |> ignore;;
 
val myLVItem02 : ListViewItem = ListViewItem: {item02col01}
 
> let myLVItem03 = new ListViewItem([|"item03col01";"item03col02";"item03col03";"item03col04"|])//4個の場合
myListView.Items.Add(myLVItem03) |> ignore;;
 
val myLVItem03 : ListViewItem = ListViewItem: {item03col01}
 
結果は下の通りで、足りない場合は「空白」、多い場合は「表示されない」ということになります。
(ただ多い場合でも「表示されない」だけで、myLVItem03のSubItemsは4個です。) 
 
816-4.jpg 
 
それでは少しListViewSubItem型について調べてみます。
 
> let item01Sub0 = myLVItem01.SubItems.[0];;
val item01Sub0 : ListViewItem.ListViewSubItem = ListViewSubItem: {item01col01}
 
> item01Sub0;;
val it : ListViewItem.ListViewSubItem =
  ListViewSubItem: {item01col01}
    {BackColor = Color [Window];
     Bounds = {X=0,Y=24,Width=281,Height=16};
     Font = [Font: Name=MS UI Gothic, Size=9, Units=3, GdiCharSet=128, GdiVerticalFont=False];
     ForeColor = Color [WindowText];
     Name = "";
     Tag = null;
     Text = "item01col01";}
 
見ての通り基本的に保持する値はstring型の値だけのようです。
 
 
ListViewの仕切り線を表示するには次のようにします。
 
myListView.GridLines <- true
 
列幅を自動調整するにはColumnHeaderのWidthを-1に設定します。
 
(myListView.Columns.Item 0).Width   <- -1 //一番左端の列の幅を自動調整にした
 
左中央右揃えを指定するにはColumnHeaderのTextAlignプロパティを利用します。
 
(myListView.Columns.Item 1).TextAlign <- HorizontalAlignment.Right
//左から2番目の列を右揃えにした
 
(?)(myListView.Columns.Item 0).TextAlign <- HorizontalAlignment.Right
はうまくいきません。なぜだろう?
 
それでは、列名と幅と文字揃えの方法のタプルのリストを渡すと、列見出しの設定をしてくれる関数と
item追加用の関数を定義してみます。
 
○列名と幅と文字揃えの方法のタプルのリストを渡すと、列見出しの設定をしてくれる関数
 
let setUpListView (targetListView : ListView) (colTextWidthLst : list<string*int*HorizontalAlignment>) =
    
    targetListView.View <- View.Details
    targetListView.GridLines <- true
 
    colTextWidthLst
    |> List.iter(fun (text,width,algin) ->
                    targetListView.Columns.Add (new ColumnHeader(Text = text,Width = width,TextAlign=algin)) |> ignore) 
 
○item追加用の関数
 
let myAddItem (targetListView : ListView) (itemData : list<list<string>>) =
    List.map (fun strLst -> targetListView.Items.Add(new ListViewItem (Array.ofList strLst)) |> ignore) itemData
    |> ignore
 
 
このように定義しておいて
 
let mainForm = new Form(Width = 480, Height = 200, Text = "MyListView Window")
mainForm.Show() |> ignore;;
 
let myListView = new ListView(Location = new Point(30,20),Width = 400)
mainForm.Controls.Add(myListView)
 
[("ID",70,HorizontalAlignment.Right);("品目",160,HorizontalAlignment.Left);("価格",100,HorizontalAlignment.Right)]
|> setUpListView myListView
 
[["21";"りんご";"178"];["1";"みかん";"12"];["111";"バナナ";"214"]]
|> myAddItem myListView
 
とすると、以下のように表示されます。(1列目がやっぱり、右揃えになってくれませんが。) 
 
816-5.jpg 
 
最後にitem(行)の並べ替えですが、これは次のように行うことができます。
 
まずSystem.Collections.IComparerインターフェイスを実装したクラスを準備しておきます。
これにはCompare (x:obj,y:obj)というメソッドを実装する必要があります。
実際に使用される時にはx,yにはListViewItem型の値が渡されるので、これをキャストしたうえで
x,yを比較して、-1,0,1のいずれかの値を返すようにします。
ここでは、何列目をターゲットにして整列するかも指定したいので、コンストラクタは、何列目が対象かというint型の値を引数に取ることにします。
 
type ListViewItemComparer(col:int) =
    interface System.Collections.IComparer with
      member this.Compare (x:obj,y:obj) = //x,yにはListViewItemのインスタンスが渡される(キャストが必要)
         let l = ((x :?> ListViewItem).SubItems.Item col).Text
         let r = ((y :?> ListViewItem).SubItems.Item col).Text
         String.Compare (l,r)
 
実際にソートするにはListViewのListViewItemSorterプロパティにこのクラスのインスタンスを設定します。(設定した段階で自動的にソートが行われます。)
 
> myListView.ListViewItemSorter <- (new ListViewItemComparer (1));;
val it : unit = () 
 
816-6.jpg 
 
> myListView.ListViewItemSorter <- (new ListViewItemComparer (2));;
val it : unit = () 
 
816-7.jpg 

 
> myListView.ListViewItemSorter <- (new ListViewItemComparer (0));;
val it : unit = () 
 
816-8.jpg 
 
 
これらは、文字列のソートですので、数字としてのソートではありません。数字としてのソート等はどうするのかというのは次回やります。
スポンサーサイト

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

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

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

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

この人とブロともになる

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