ごまなつ Blog

楽しく働ける世界を目指して

【C#】ListViewのSelectedIndex変更禁止に立ちふさがる壁

C#のListViewにて、ある条件のときは選択しているアイテムを変更させないようにしたいことがありました。アイテム変更なのでitemSelectionChangedを用いました。選択しているアイテムの変更は、

  1. 選択しているアイテムの選択が外れる
  2. 何も選択されていない状態
  3. クリックしたアイテムが選択される

という順番になっています。

避けるべきこと

上記の2においては、何も選択されていない状態なのでインデックスが-1になります。また、3において選択操作をキャンセルすると何も選択していない状態になります。これを回避する必要があります。

使えるもの

ListViewItem型の変数を用意して、itemSelectionChangedの中で使うと選択しているアイテムになります。e.itemは変更先のアイテムです。また、MouseUpイベントハンドラ(マウスクリックを離したとき)を用いて選択しているアイテムにインデックスを戻せば、アイテムを変更させないことができます。

問題

この考えに従って普通に書くと、itemSelectionChangedの中で選択しているアイテムを変更することになるので、処理の順番などから思わぬ動作になることがあります。私も、選択が消えることが多くありました。よって、Task.Runを用いてアイテム変更動作のタイミングをずらしました。

追加要望

ここで、右クリックメニューを追加してほしいという要望が来ました。上記の動作を持ったまま行うと、選択しているアイテムに選択を戻すため、選択しているアイテムが選択状態になる(背景青に白抜きの文字になる)が、右クリックメニューはクリック位置に出るという違和感満載の見た目になりました。なにか良い方法があるとよいのですが・・・・・・