开发者

How can I catch the autosize double-click event on a listview in VB.NET?

I am using Visual Studio 2008 and VB.NET. I've got a listview control on my form and I've added columns using the windows forms designer. As you know, if you double-click on the sizer or divider or whatever you want to call it between two columns, the column on the left will autosize (unless you disable that). How can I catch this specific event? The ColumnWidthChanged event and the DoubleClick event are likely candidates, but in the ColumnWidthChanged event, there's no way I can see to determine if it was an autosize. Similarly, there's no simple way to catch what was clicked exactly with the DoubleClick event. Does anyone have any ideas how I can catch this specific event t开发者_StackOverflow中文版ype?


Detecting events on a listview's header is quite tricky.

You will need to create your own header to replace the one that it normally uses, and then listen to the appropriate messages. There aren't any specific ones for column resize handles, as far as I know.

The following class subclasses ListView and adds a handler that detects a double-click between columns. That is as close as it gets, I think.

I hope it will help you out somewhat.

    Class MyListView
        Inherits ListView

        Protected Overrides Sub CreateHandle()
            MyBase.CreateHandle()
            New HeaderControl(Me)
        End Sub

        Private Class HeaderControl
            Inherits NativeWindow
            Private _parent As ListView = Nothing

            <DllImport("User32.dll", CharSet := CharSet.Auto, SetLastError := True)> _
            Public Shared Function SendMessage(hWnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
            End Function

            Public Sub New(parent As ListView)
                _parent = parent

                Dim header As IntPtr = SendMessage(parent.Handle, (&H1000 + 31), IntPtr.Zero, IntPtr.Zero)
                Me.AssignHandle(header)
            End Sub


            Protected Overrides Sub WndProc(ByRef message As Message)
                Const  WM_LBUTTONDBLCLK As Integer = &H203

                Select Case message.Msg
                    Case WM_LBUTTONDBLCLK
                        Dim position As Point = Control.MousePosition
                        Dim relative As Point = _parent.PointToClient(position)

                        Dim rightBorder As Integer = 0
                        For Each c As ColumnHeader In _parent.Columns
                            rightBorder += c.Width
                            If relative.X > (rightBorder - 6) AndAlso relative.X < (rightBorder + 6) Then
                                MessageBox.Show([String].Format("Double-click after column '{0}'", c.Text))
                            End If
                        Next
                        Exit Select
                End Select


                MyBase.WndProc(message)


            End Sub

        End Class
    End Class

You will need to include a using System.Runtime.InteropServices; statement for this to work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜