[.NET] ListViewのSelectedItemsをcastする

System.Windows.Controls.ListViewにはListの選択モードがある。1個を選択するか、複数を同時に選択するか設定する。
複数を選択する場合には、選択したもののcollectionをSelectedItemsプロパティを通じて取得する。

SelectedItemsプロパティをgetするとIListが返る。SelectedItemのように一度のcastで目的のclassオブジェクトが手に入らないので、さらにIListからcastして使うケースが多い。
この処理が少し手間がかかるのでコミュニティサイトには、うまくいかない、とか、どうしたらいいのか、というポストがよく上がる。

リストを取得するのは以下の回答がおそらく定番のやり方だ。

Casting System.Windows.Controls.SelectedItemCollection

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7dedf4ad-7459-494d-9c1d-452235499ce7

上記で回答とされたやり方はCastメソッドを使う。
varはあまり使いたくないのだが、こういうときには仕方がないと割り切った方がいいのだろう。
デバッガで動作させて中身を見るとvarの代わりに IEnumerable で受けることもできるようだ。

System.Collections.IList items = (System.Collections.IList) param;
var collection = items.Cast<PuzzleViewModel>();

投稿にある質問者は以下のようにしている。これだとエラーが発生する。

private void DeletePuzzle(object param)
{
    // Attempt to cast param
    var collection = (IEnumerable<PuzzleViewModel>param); // won't cast
   // Delete models...
}

IEnumerableインタフェースを実装しているcollectionはforeachで全数処理ができるのが利点だ。

注意点としては、foreachで使うリストはreadonlyでなければならない(変更されると例外が発生する)ため、リストを変更する場合は使えない。

自分の場合は、Viewで選択したものを削除する処理なのでforeachが使えないだった。そのため消去の対象となるIListオブジェクトの長さをみることで判定を行う。

     public void OnKeyDown(Object sender, KeyEventArgs args)
        {
            ListView lst = sender as ListView;
            IList ilist =  lst.SelectedItems;

             if (lst.SelectedItems == null)
                  return;

            if (args.Key == Key.Delete)
            {
                while(ilist.Count > 0)
                {
         MyClass myobj;
                      myobj = (MyClass)ilist[0];

                      .........

                }
            }
      }

Countが1以上であれば、[0]は必ず存在するという仮定を置いている。SelectedItemsをIListに代入したものが index 0から隙間なく配置されているものと想定。
今のところこれは間違っていないようだ。

また、SelectedItemsはListの変化に応じて動的に変わるため、whileループの中でSelectedIndexをsetするとSelectedItemsを参照するilistの内容もそれにつれて変わる。
最初はそれがわからず、ilist.Countがゼロにならないというバグを入れてしまった。

広告

コメントを残す

コメントを投稿するには、以下のいずれかでログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。