DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ListViewでのダブルクリック

環境/言語:[C# .NET Framework1.1]
分類:[.NET]

はじめまして。あくもと申します。
いつも参考にさせていただいております。

初歩的な質問で恐縮ですが、ListViewで表示方法をDetailにし、
チェックボックスを使用するとき、アイテムをダブルクリックすると
チェックボックスにチェックが入ります。
この動作を禁止することは出来ないのでしょうか?

イベントの動きを確認すると、チェックを入れてからダブルクリックの
イベントが発生するため、チェックイベントが単なるチェックと
ダブルクリックによるチェックを区別する術がないように思えます。
チェックイベントを単なるチェックの時のみ発生させ、ダブルクリックのときは
起こって欲しくない、というのが理想の動きなので、これでは具合が
よろしくありません。

どなたかご存知の方がいらっしゃいましたらご教授願います。
それでは、よろしくお願い致します。
ダブルクリックが最終イベントである限り無理だと思います。

代替案としては、CheckBoxesプロパティをFalseにして、
チェック/チェック無しのイメージ含むImageListを設定して表示を切り替えることでしょうか。
ただし依然としてイベントの順序は変わらないのでそれだけではだめで
マウスポインタの範囲がイメージとそれ以外で区別する必要があります。
・イメージ上 − ダブルクリックは2回のクリックとみなしてイメージの切り替え
・イメージ以外 − ダブルクリックの判定のみでイメージの切り替え無し
ListView の派生クラスを作り、WndProc をオーバーライドして WM_LBUTTONDBLCLK を握りつぶす(MyBase.WndProc を呼ばない)ってことになるかしらん。
// DoubleClick イベントも発生しなくなりますが。
> ListView の派生クラスを作り、WndProc をオーバーライドして WM_LBUTTONDBLCLK を握りつぶす(MyBase.WndProc を呼ばない)ってことになるかしらん。

フォローありがとうございます。

> // DoubleClick イベントも発生しなくなりますが。

おっとっと、、って私は任意の処理があるつもりで書いてました。
それが無ければ一番楽ですね。
ご回答ありがとうございます。

> ダブルクリックが最終イベントである限り無理だと思います。

む…。

> 代替案としては、CheckBoxesプロパティをFalseにして、
> チェック/チェック無しのイメージ含むImageListを設定して表示を切り替えることでしょうか。

マウスの座標をクリック時に取得し、その位置からチェックボックスの
クリックなのかそれ以外なのかを判定する…なんて方法でないと
駄目なんですね。

自分の調べ不足で、単純にプロパティがあるとかだったらよかったのですが。
なかなか難しいですね。
ご回答ありがとうございます。

>>// DoubleClick イベントも発生しなくなりますが。
>
> おっとっと、、って私は任意の処理があるつもりで書いてました。
> それが無ければ一番楽ですね。

今回はダブルクリック・チェックのどちらにもイベントがあるため、
発生しなくなるとちょっときついですね。
そもそもダブルクリックで勝手にチェックを入れてくれるListViewの作りに
疑問を感じますが…。

別回答でのまどかさんの案で処理をしようと思います。
Hongliangさん、まどかさん、お早い回答をありがとうございました。
解決済み!
2006/08/24(Thu) 04:12:44 編集(投稿者)

ダブルクリックでItemCheckイベントが発生する場合、その前にMouseDownイベントが2回発生するようです。つまり、MouseDownイベントが2回目に発生してからItemCheckイベントが発生すれば、ダブルクリックによりチェック状態が変化したと考えられそうです。

こんな感じで試してみました。

private bool _doubleClicked = false;

private void listView1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (this._doubleClicked)
Console.WriteLine("ダブルクリックされました");
}

private void listView1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Clicks == 2)
this._doubleClicked = true;
else
this._doubleClicked = false;
}

private void listView1_DoubleClick(object sender, EventArgs e)
{
this._doubleClicked = false;
}
解決済み!
2006/08/25(Fri) 10:42:01 編集(投稿者)

ご返答、ありがとうございます。
管理人さまのアドバイスを元に、以下のように作成してみました。

private bool _doubleClick = false;

private void listView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
// マウスボタンが押された回数を判定
if( e.Clicks == 2 )
{
// 2回のときはダブルクリック判定とする
this._doubleClick = true;
}
else
{
// それ以外は通常クリックとして処理
this._doubleClick = false;
}
}

private void listView_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
{
// ダブルクリックのときはチェック変更をキャンセル
if( this._doubleClick )
{
if( e.NewValue == CheckState.Checked )
{
e.NewValue = CheckState.Unchecked;
}
else
{
e.NewValue = CheckState.Checked;
}
}

ListView lv = (ListView)sender;

// 該当アイテムの状態が変更されるか確認
if(( lv.Items[e.Index].Checked && e.NewValue == CheckState.Unchecked )
|| ( lv.Items[e.Index].Checked == false && e.NewValue == CheckState.Checked ))
{
MessageBox.Show( "チェック変更", "information" );
}
}

private void listView_DoubleClick(object sender, System.EventArgs e)
{
// イベント発生時にフラグを落とす
this._doubleClick = false;

MessageBox.Show( "ダブルクリック", "information" );
}

ダブルクリックのときはダブルクリックメッセージが表示され、
チェックボックス変更のときに、変更メッセージが表示されることを
確認しました。

こういう方法もあるんですね〜。まだまだ勉強不足です。
貴重な回答をどうもありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板