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

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

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

ListViewの選択が外れる対処

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

■93954 / inTopicNo.1)  ListViewの選択が外れる対処
  
□投稿者/ harunex (1回)-(2020/02/27(Thu) 09:51:24)

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

こんにちは。

ListViewについて質問させてください。

例えば、ListViewにアイテムが5つ表示されている状態で、6番目以降(何も無い空白の項目)を
クリックすると、元々選択されているアイテムの選択が外れます。

これを防止するために、何か対策ございませんでしょうか。

どうかよろしくお願いいたします。
引用返信 編集キー/
■93957 / inTopicNo.2)  Re[1]: ListViewの選択が外れる対処
□投稿者/ WebSurfer (2029回)-(2020/02/27(Thu) 10:52:54)
No93954 (harunex さん) に返信

> ListViewについて質問させてください。

何を作っているか(Windows Forms? WPF? ASP.NET Web Forms? その他?)と
開発環境(OS, .NET, Visual Studio のバージョンなど)を書きませんか?

ListView というのは Windows Forms, WPF, ASP.NET Web Forms のいずれに
もあるのですよ。

引用返信 編集キー/
■93958 / inTopicNo.3)  Re[1]: ListViewの選択が外れる対処
□投稿者/ 魔界の仮面弁士 (2571回)-(2020/02/27(Thu) 10:54:29)
2020/02/27(Thu) 11:02:35 編集(投稿者)

No93954 (harunex さん) に返信
> 例えば、ListViewにアイテムが5つ表示されている状態で、

System.Windows.Controls.ListView ではなく、
System.Windows.Forms.ListView の話で良いでしょうか。


> 6番目以降(何も無い空白の項目)を
> クリックすると、元々選択されているアイテムの選択が外れます。

Windows のエクスプローラーでファイル一覧を表示している時、
余白部をクリックすると、同じ動作になりますね。


> これを防止するために、何か対策ございませんでしょうか。

SelectionMode = One な ListBox であれば、選択が外れないのですよね。
Multi何某を指定した場合は、最後の選択が解除されてしまいますが。


ListView の場合は、どうあっても最後の選択が解除されるので、
WndProc を捕らえて、余白クリック時の手続きを握りつぶすという
強硬手段ぐらいしか思い当たらないです。

とりあえずサンプル。
ただし MultiSelect 時のドラッグ選択機能も失われてしまう点に注意。

Public Class Form1
 Private hook As ListViewHook
 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  hook = New ListViewHook(ListView1)
 End Sub
 Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
  hook.ReleaseHandle()
 End Sub
End Class

' 下記では NativeWindow で WndProc を捕らえていますが、解放の手間が発生するので、
' 実際には ListView を Inherits して WndProc を捕らえる方法をお奨めします
Public Class ListViewHook
 Inherits NativeWindow
 Private target As ListView
 Public Sub New(lvw As ListView)
  If lvw Is Nothing Then Throw New ArgumentNullException(NameOf(lvw))
  target = lvw
  AssignHandle(lvw.Handle)
 End Sub
 Protected Overrides Sub WndProc(ByRef m As Message)
  Select Case m.Msg
   Case &H201 To &H209 'WM_LBUTTONDOWN〜WM_MBUTTONDBLCLK
    Dim lp As Integer
    If IntPtr.Size = 8 Then
     lp = CInt(m.LParam.ToInt64() And &HFFFFFFFFL)
    Else
     lp = m.LParam.ToInt32()
    End If
    Dim pos As New Point(lp And &HFFFF, lp >> 16)
    Dim hit = target.HitTest(pos)
    Select Case hit.Location
     Case ListViewHitTestLocations.AboveClientArea
     Case ListViewHitTestLocations.BelowClientArea
     Case ListViewHitTestLocations.LeftOfClientArea
     Case ListViewHitTestLocations.RightOfClientArea
     Case ListViewHitTestLocations.None
      Return
    End Select
  End Select
  MyBase.WndProc(m)
 End Sub
End Class
引用返信 編集キー/
■93959 / inTopicNo.4)  Re[2]: ListViewの選択が外れる対処
□投稿者/ harunex (2回)-(2020/02/27(Thu) 10:56:44)
No93957 (WebSurfer さん) に返信
> ■No93954 (harunex さん) に返信
>
>>ListViewについて質問させてください。
>
> 何を作っているか(Windows Forms? WPF? ASP.NET Web Forms? その他?)と
> 開発環境(OS, .NET, Visual Studio のバージョンなど)を書きませんか?
>
> ListView というのは Windows Forms, WPF, ASP.NET Web Forms のいずれに
> もあるのですよ。
>
ご指摘ありがとうございます。

Windows Formsで、開発環境 Windows10,VB2010です。
引用返信 編集キー/
■93960 / inTopicNo.5)  Re[2]: ListViewの選択が外れる対処
□投稿者/ harunex (3回)-(2020/02/27(Thu) 11:04:57)
No93958 (魔界の仮面弁士 さん) に返信
> 2020/02/27(Thu) 11:02:35 編集(投稿者)
>
> ■No93954 (harunex さん) に返信
>>例えば、ListViewにアイテムが5つ表示されている状態で、
>
> System.Windows.Controls.ListView ではなく、
> System.Windows.Forms.ListView の話で良いでしょうか。
>
>
>>6番目以降(何も無い空白の項目)を
>>クリックすると、元々選択されているアイテムの選択が外れます。
>
> Windows のエクスプローラーでファイル一覧を表示している時、
> 余白部をクリックすると、同じ動作になりますね。
>
>
>>これを防止するために、何か対策ございませんでしょうか。
>
> SelectionMode = One な ListBox であれば、選択が外れないのですよね。
> Multi何某を指定した場合は、最後の選択が解除されてしまいますが。
>
>
> ListView の場合は、どうあっても最後の選択が解除されるので、
> WndProc を捕らえて、余白クリック時の手続きを握りつぶすという
> 強硬手段ぐらいしか思い当たらないです。
>
> とりあえずサンプル。
> ただし MultiSelect 時のドラッグ選択機能も失われてしまう点に注意。
>
> Public Class Form1
>  Private hook As ListViewHook
>  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
>   hook = New ListViewHook(ListView1)
>  End Sub
>  Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
>   hook.ReleaseHandle()
>  End Sub
> End Class
>
> ' 下記では NativeWindow で WndProc を捕らえていますが、解放の手間が発生するので、
> ' 実際には ListView を Inherits して WndProc を捕らえる方法をお奨めします
> Public Class ListViewHook
>  Inherits NativeWindow
>  Private target As ListView
>  Public Sub New(lvw As ListView)
>   If lvw Is Nothing Then Throw New ArgumentNullException(NameOf(lvw))
>   target = lvw
>   AssignHandle(lvw.Handle)
>  End Sub
>  Protected Overrides Sub WndProc(ByRef m As Message)
>   Select Case m.Msg
>    Case &H201 To &H209 'WM_LBUTTONDOWN〜WM_MBUTTONDBLCLK
>     Dim lp As Integer
>     If IntPtr.Size = 8 Then
>      lp = CInt(m.LParam.ToInt64() And &HFFFFFFFFL)
>     Else
>      lp = m.LParam.ToInt32()
>     End If
>     Dim pos As New Point(lp And &HFFFF, lp >> 16)
>     Dim hit = target.HitTest(pos)
>     Select Case hit.Location
>      Case ListViewHitTestLocations.AboveClientArea
>      Case ListViewHitTestLocations.BelowClientArea
>      Case ListViewHitTestLocations.LeftOfClientArea
>      Case ListViewHitTestLocations.RightOfClientArea
>      Case ListViewHitTestLocations.None
>       Return
>     End Select
>   End Select
>   MyBase.WndProc(m)
>  End Sub
> End Class

魔界の仮面弁士さま

そうなのですね・・。

素直にListBoxで実装しようと思います。

ご返答・サンプル、ありがとうございました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


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

このトピックに書きこむ