C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: DataGridViewの行選択解除処理について


(過去ログ 87 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■51973 / inTopicNo.1)  DataGridViewの行選択解除処理について
  
□投稿者/ エル (2回)-(2010/07/27(Tue) 15:39:55)

分類:[VB.NET/VB2005 以降] 

分類:[VB.NET 2005] 

開発環境
Microsoft WindowsXP
Microsoft Visual Studio 2005

いつもお世話になっております。
ご覧頂き、ありがとうございます。
お手数ですが、一点質問させてください。

下記ソースにて、フォーム表示後例えば一行目をクリックし、「'ここで一時停止」の所でデバッグにて一時停止したとします。
この場合、デバッグ中のDataGridView1.SelectedRows.Countは 2 となります。
(ソースでSelected = Trueにした 4行目、クリックした1行目が選択されているはずです。)

ところが、一時停止を解除し全処理を終了するとクリックした行のみ選択され、ソースで設定した4行目は選択解除されています。
この、「4行目の選択が解除される処理」はどのようなしくみで処理されているか、ご存知の方はいらっしゃいますか?

申し訳ありませんが、ご教示よろしくお願い致します。


以下、ソースになります。

Imports System.Windows.Forms

Public Class FormTest1

Public Sub New()
InitializeComponent()
End Sub

Private Sub FormTest1_load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
setGridData()
End Sub

Private Sub setGridData()
With Me.DataGridView1
.Columns.Add("AAA", "AAA")
.Columns.Add("BBB", "BBB")
.Columns.Add("CCC", "CCC")
.Columns.Add("DDD", "DDD")

Dim cnt As Integer = 0
While cnt < 5
.Rows.Add()
cnt += 1
End While
For i As Integer = 0 To .Rows.Count - 1
.Item("AAA", i).Value = "AAA" & i
.Item("BBB", i).Value = "BBB" & i
.Item("CCC", i).Value = "CCC" & i
Next
End With
End Sub

Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown
DataGridView1.Rows(3).Selected = True
For i As Integer = 0 To DataGridView1.Columns.Count - 1
DataGridView1.Rows(3).Cells(i).Selected = True
Next

'ここで一時停止
Console.WriteLine()
End Sub

End Class
引用返信 編集キー/
■51993 / inTopicNo.2)  Re[1]: DataGridViewの行選択解除処理について
□投稿者/ すなふきぬ (22回)-(2010/07/28(Wed) 11:33:05)
No51973 (エル さん) に返信
> 分類:[VB.NET 2005] 

> 下記ソースにて、フォーム表示後例えば一行目をクリックし、「'ここで一時停止」の所でデバッグにて一時停止したとします。
> この場合、デバッグ中のDataGridView1.SelectedRows.Countは 2 となります。
> (ソースでSelected = Trueにした 4行目、クリックした1行目が選択されているはずです。)

本当にSelectedRows.Countが2ですか?指定された箇所にブレークを張って、起動直後に1行目をクリックしてもSelectedRows.Countは1でした。
他に何か条件とかありませんか?(例えばCtrlキーを押しながら1行目をクリックとか)


・・・と書いてたらわかった。

Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown

Handles DataGridView1.MouseDown

これです。正しくCellEnterイベントで実装したら解除されず4行目も選択されました。


Private Sub DataGridView1_CellEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter

この辺がわからない場合は、勝手に書き換えない方が良いと思います。(特にHandlesなんかは右端に隠れちゃったりするので)

あと、setGridData()の中で行追加している部分ですが、エラーになったので.Rows.Add(5)に変えた方が良いかもしれません。
引用返信 編集キー/
■51994 / inTopicNo.3)  Re[2]: DataGridViewの行選択解除処理について
□投稿者/ エル (3回)-(2010/07/28(Wed) 16:26:16)
No51993 (すなふきぬ さん) に返信
> ■No51973 (エル さん) に返信
>>分類:[VB.NET 2005] 

すなふきぬ様、ご回答ありがとうございます。
お忙しい中お手数をお掛けしました。また丁寧なご対応恐れ入ります。


> 本当にSelectedRows.Countが2ですか?指定された箇所にブレークを張って、起動直後に1行目をクリックしてもSelectedRows.Countは1でした。
> 他に何か条件とかありませんか?(例えばCtrlキーを押しながら1行目をクリックとか)
MouseDown直後は選択行が反映しないので、起動直後に行をクリックしてもSelectedRows.Countは1ですよね・・・。
上記大変失礼しました。

私の確認ミスで、複数回繰り返していて前回クリックした行情報が残った為、SelectedRows.Countが2になっていた様です。
上記は具体例を出すつもりがより分かり辛くなりそうですので無しとして下さい。


> Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown
>
> Handles DataGridView1.MouseDown
>
> これです。正しくCellEnterイベントで実装したら解除されず4行目も選択されました。
>
>
> Private Sub DataGridView1_CellEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
こちらも申し訳ありません。冷や汗が出てきました・・・。

先日はかなり混乱していたこともあり、色々と記述ミスがありました。
再度質問の要点をまとめさせて頂きます。


・関数は下記になります。
Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown

・現象
MouseDownが実行された後、MouseDownイベント内で複数行選択処理を実行しても、結果的に選択された行のみが選択状態になります。
(上記はCtrlキーなどを押下しないことを前提としてください。)

・質問
MouseDownイベント内では複数選択されているのに、MouseDown終了後に一行のみ選択状態になるのは、どうしてなのでしょうか。
(なぜ選択したはずの他行は解除されてしまうのでしょうか。)
この、ある種勝手に変更してくれる「しくみ」が確認したかった次第です。

極論では、この勝手に変更する処理をキャンセルさせたかったのですが・・・。
その様な「仕様」であり、処理内容がブラックボックスなものでしたら、その様に教えて頂けるとありがたいです。


> この辺がわからない場合は、勝手に書き換えない方が良いと思います。(特にHandlesなんかは右端に隠れちゃったりするので)
>
> あと、setGridData()の中で行追加している部分ですが、エラーになったので.Rows.Add(5)に変えた方が良いかもしれません。
上記アドバイスありがとうございます。
また、.Rows.Add(5)と記述出来ることを知りませんでした。勉強になります。


度々の質問となりお手数をお掛けしますが、よろしくお願い致します。

引用返信 編集キー/
■51995 / inTopicNo.4)  Re[3]: DataGridViewの行選択解除処理について
□投稿者/ なし (10回)-(2010/07/28(Wed) 17:48:04)
No51994 (エル さん) に返信

こんにちは。

何もコードを書いていないDataGridViewでも、
マウスで4行目を選択した後、他のセルをクリックすると、
4行目の選択は解除されますよね。
次に、もう一度4行目を選択し、
今度はコントロールキーを押しながら他のセルをクリックすると、
この場合は4行目の選択は解除されませんよね。

これと同じ作用が働いているんだと思います。

エルさんのコードを書いた場合でも、
コントロールキーを押しながらセルをクリックした場合には、
コードで選択した4行目はちゃんと選択されたままになります。

つまり、このイベントの発生中では、選択状態を変更してもだめということになるので、
変な方法かもしれないけど、↓みたいにイベントが終わった後にすればできました。

Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown
Me.BeginInvoke(New MethodInvoker(AddressOf SetStateSelectedOfRow))
End Sub

Private Sub SetStateSelectedOfRow()
DataGridView1.Rows(3).Selected = True
End Sub

引用返信 編集キー/
■51996 / inTopicNo.5)  Re[4]: DataGridViewの行選択解除処理について
□投稿者/ なし (11回)-(2010/07/28(Wed) 18:37:55)
No51995 (なし さん) に返信

1点、ちゃんと書けてなかったので追加します。

MouseDownのイベントハンドラを呼び出している側の、呼び出し後の処理に、
選択を解除する部分があるんだと思います。
その処理は、通常のマウス操作でのセル選択時には必要な自然な処理だと思います。

引用返信 編集キー/
■52004 / inTopicNo.6)  Re[5]: DataGridViewの行選択解除処理について
□投稿者/ エル (4回)-(2010/07/29(Thu) 10:18:58)
なし様、ご回答ありがとうございます。
お忙しい中お時間を頂き、大変恐縮です。


> 何もコードを書いていないDataGridViewでも、
> マウスで4行目を選択した後、他のセルをクリックすると、
> 4行目の選択は解除されますよね。
> 次に、もう一度4行目を選択し、
> 今度はコントロールキーを押しながら他のセルをクリックすると、
> この場合は4行目の選択は解除されませんよね。

> これと同じ作用が働いているんだと思います。

> エルさんのコードを書いた場合でも、
> コントロールキーを押しながらセルをクリックした場合には、
> コードで選択した4行目はちゃんと選択されたままになります。
そうなんですよね。
複数選択 = CtrlキーやShiftキーありきな動作ということで。


> つまり、このイベントの発生中では、選択状態を変更してもだめということになるので、
やはりその様な結論となりますか。
進もうか戻ろうかとずっと考えていたので、一つの結論が出るのは助かります。


> 変な方法かもしれないけど、↓みたいにイベントが終わった後にすればできました。

> Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown
> Me.BeginInvoke(New MethodInvoker(AddressOf SetStateSelectedOfRow))
> End Sub

> Private Sub SetStateSelectedOfRow()
> DataGridView1.Rows(3).Selected = True
> End Sub
非同期実行・・・なるほど、考えの外でした。大変勉強になります。

ヘルプ等を見る限り、MouseDown後のイベント発生順序はMouseUp、MouseLeaveとあり、この中で処理するには意味が違いますし、
CellEnter や SelectionChanged辺りだと他の制御に大きく関わってしまうだろうしで困っておりました。

上記の方法で希望する制御が行えるようですので、参考にさせて頂きます。


> MouseDownのイベントハンドラを呼び出している側の、呼び出し後の処理に、
> 選択を解除する部分があるんだと思います。
> その処理は、通常のマウス操作でのセル選択時には必要な自然な処理だと思います。
私もそうだと思うのですが、手を出せない部分なのでしょうかね・・・。
そのイベント処理内で e.Canelの様な停止処理が行えないだろうか?と考えたところから、本件の疑問が浮かびました。

ともあれ、なし様のアドバイスで解決出来そうです。


なし様、すなふきぬ様、ありがとうございました。
解決済み
引用返信 編集キー/
■52014 / inTopicNo.7)  Re[6]: DataGridViewの行選択解除処理について
□投稿者/ エル (5回)-(2010/07/29(Thu) 11:34:23)
お世話になっております。

蛇足ですが、せっかくですのでControl.BeginInvokeを実行する際、引数を与えて実行するやり方を下記に記述します。
MethodInvokerは引数・戻り値なしの様ですので、他の方の参考になればと。

Delegateステートメントはもちろん、Functionでも実装可能です。(詳しくはヘルプ等をご確認ください。)


以下、ソースになります。

Imports System.Windows.Forms

Public Class FormTest1

Public Sub New()
InitializeComponent()
End Sub

Delegate Sub testDelegate(ByVal index As Integer)

Private Sub FormTest1_load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
setGridData()
End Sub

Private Sub setGridData()
With Me.DataGridView1
.Columns.Add("AAA", "AAA")
.Columns.Add("BBB", "BBB")
.Columns.Add("CCC", "CCC")
.Columns.Add("DDD", "DDD")

Dim cnt As Integer = 0
'While cnt < 5
' .Rows.Add()
' cnt += 1
'End While
.Rows.Add(5)

For i As Integer = 0 To .Rows.Count - 1
.Item("AAA", i).Value = "AAA" & i
.Item("BBB", i).Value = "BBB" & i
.Item("CCC", i).Value = "CCC" & i
Next
End With
End Sub

Private Sub DataGridView1_(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown
'DataGridView1.Rows(3).Selected = True
'For i As Integer = 0 To DataGridView1.Columns.Count - 1
' DataGridView1.Rows(3).Cells(i).Selected = True
'Next

'MethodInvokeを使用した場合
'Me.BeginInvoke(New MethodInvoker(AddressOf SetStateSelectedOfRow))

'デリゲートを実装した場合
Dim del As testDelegate = AddressOf Me.SetStateSelectedOfRow
Dim obj(0) As Object
obj(0) = 3

Me.BeginInvoke(del, obj)
End Sub

Private Sub SetStateSelectedOfRow()
DataGridView1.Rows(3).Selected = True
End Sub

Private Sub SetStateSelectedOfRow(ByVal index As Integer)
If index < 0 Then
Exit Sub
End If

DataGridView1.Rows(index).Selected = True
End Sub

End Class
引用返信 編集キー/
■52021 / inTopicNo.8)  Re[7]: DataGridViewの行選択解除処理について
□投稿者/ エル (6回)-(2010/07/29(Thu) 12:00:13)
解決済みのチェックが外れてました・・・
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -