none
Is this the right way to SetExtendedStyle for a listview RRS feed

  • Question

  • Is this the right way to SetExtendedStyle for a listview
    I want to make listview check the item if selected by mouse

    
    

    <DllImport("user32.dll", CharSet:=CharSet.Auto)>
                Private Shared Function SendMessage(handle As IntPtr, messg As Integer, wparam As Integer, lparam As Integer) As Integer
                End Function
    
                Public Sub SetExtendedStyle(control As ListView, exStyle As ListViewExtendedStyles, enabled As Boolean)
                    Dim styles As ListViewExtendedStyles
                    styles = CType(SendMessage(control.Handle, CType(ListViewMessages.GetExtendedStyle, Integer), 0, 0), ListViewExtendedStyles)
                    If enabled Then
                        styles = styles Or exStyle
                    Else
                        styles -= styles And exStyle
                    End If
                    SendMessage(control.Handle, CType(ListViewMessages.SetExtendedStyle, Integer), 0, CType(styles, Integer))
                End Sub

        Public Enum ListViewExtendedStyles
            ''' <summary>
            ''' LVS_EX_GRIDLINES
            ''' </summary>
            GridLines = &H1
            ''' <summary>
            ''' LVS_EX_SUBITEMIMAGES
            ''' </summary>
            SubItemImages = &H2
            ''' <summary>
            ''' LVS_EX_CHECKBOXES
            ''' </summary>
            CheckBoxes = &H4
            ''' <summary>
            ''' LVS_EX_TRACKSELECT
            ''' </summary>
            TrackSelect = &H8
            ''' <summary>
            ''' LVS_EX_HEADERDRAGDROP
            ''' </summary>
            HeaderDragDrop = &H10
            ''' <summary>
            ''' LVS_EX_FULLROWSELECT
            ''' </summary>
            FullRowSelect = &H20
            ''' <summary>
            ''' LVS_EX_ONECLICKACTIVATE
            ''' </summary>
            OneClickActivate = &H40
            ''' <summary>
            ''' LVS_EX_TWOCLICKACTIVATE
            ''' </summary>
            TwoClickActivate = &H80
            ''' <summary>
            ''' LVS_EX_FLATSB
            ''' </summary>
            FlatsB = &H100
            ''' <summary>
            ''' LVS_EX_REGIONAL
            ''' </summary>
            Regional = &H200
            ''' <summary>
            ''' LVS_EX_INFOTIP
            ''' </summary>
            InfoTip = &H400
            ''' <summary>
            ''' LVS_EX_UNDERLINEHOT
            ''' </summary>
            UnderlineHot = &H800
            ''' <summary>
            ''' LVS_EX_UNDERLINECOLD
            ''' </summary>
            UnderlineCold = &H1000
            ''' <summary>
            ''' LVS_EX_MULTIWORKAREAS
            ''' </summary>
            MultilWorkAreas = &H2000
            ''' <summary>
            ''' LVS_EX_LABELTIP
            ''' </summary>
            LabelTip = &H4000
            ''' <summary>
            ''' LVS_EX_BORDERSELECT
            ''' </summary>
            BorderSelect = &H8000
            ''' <summary>
            ''' LVS_EX_DOUBLEBUFFER
            ''' </summary>
            DoubleBuffer = &H10000
            ''' <summary>
            ''' LVS_EX_HIDELABELS
            ''' </summary>
            HideLabels = &H20000
            ''' <summary>
            ''' LVS_EX_SINGLEROW
            ''' </summary>
            SingleRow = &H40000
            ''' <summary>
            ''' LVS_EX_SNAPTOGRID
            ''' </summary>
            SnapToGrid = &H80000
            ''' <summary>
            ''' LVS_EX_SIMPLESELECT
            ''' </summary>
            SimpleSelect = &H100000
    
            LVS_EX_AUTOCHECKSELECT = &H8000000
    
        End Enum
    
        Public Enum ListViewMessages
            First = &H1000
            SetExtendedStyle = (First + 54)
            GetExtendedStyle = (First + 55)
        End Enum

    SetExtendedStyle(InnerListView, ListViewExtendedStyles.LVS_EX_AUTOCHECKSELECT, True)


    Wednesday, January 10, 2018 5:35 PM

Answers

  • I want to make listview check the item if selected by mouse

      If all you want to do is to check the item(s) that are selected,  you can just use the ListView's ItemSelectionChanged event like shown in the example below.

     However,  this example can be modified to work other ways too.  For example,  if you don't want the items to be un-checked when they are un-selected,  or whatever.
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ListView1.CheckBoxes = True
            For i As Integer = 0 To 4
                ListView1.Items.Add("Item " & i.ToString)
            Next
        End Sub
    
        Private Sub ListView1_ItemSelectionChanged(sender As Object, e As ListViewItemSelectionChangedEventArgs) Handles ListView1.ItemSelectionChanged
            e.Item.Checked = e.IsSelected 'if the item is selected it is checked. If it is un-selected, it is un-checked
        End Sub
    End Class
    
    

     

     

     Also,  if you only what the items to be checked or un-checked if the mouse clicks them and not when the keyboard is used to iterate through the items,  then you could do something similar to this...

    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ListView1.CheckBoxes = True
            For i As Integer = 0 To 4
                ListView1.Items.Add("Item " & i.ToString)
            Next
        End Sub

        Private Sub ListView1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
            Dim lvi As ListViewItem = ListView1.GetItemAt(e.X, e.Y)
            If lvi IsNot Nothing Then lvi.Checked = True
            'If lvi IsNot Nothing Then lvi.Checked = Not lvi.Checked  'use this line instead,  if you want it to check/un-check when mouse clicks the item
        End Sub
    End Class

     I am sure if you experiment a little with these methods you could get it to do what you want without setting the extended styles.  8)


    If you say it can`t be done then i`ll try it

    • Marked as answer by CitySoft Thursday, January 11, 2018 12:48 AM
    Wednesday, January 10, 2018 6:40 PM
  •  Just in case you actually have the need to set other extended styles of the ListView that are not available through the .Net Listview control Properties,  you can check the below example which sets or removes the specified extended styles of a ListView.

     If you read the msdn documents for the LVM_SETEXTENDEDLISTVIEWSTYLE message,  you will see that it is not required to get the extended styles in order to set or remove the styles.  You can see that they use the wParam and lParam to specify the extended style and to determine if they should be set or removed. 

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        Private Const LVM_SETEXTENDEDSTYLE As Integer = &H1036
    
        <DllImport("user32.dll", EntryPoint:="SendMessageW")>
        Private Shared Function SendMessageW(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
        End Function
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'sets the AutoCheckSelect and CheckBoxes extended styles for ListView1 in one call to the SetListViewExtendedStyles
            SetListViewExtendedStyles(ListView1, ListViewExtendedStyles.AutoCheckSelect Or ListViewExtendedStyles.CheckBoxes, True)
            For i As Integer = 0 To 4
                ListView1.Items.Add("Item " & i.ToString)
            Next
        End Sub
    
        ''' <summary>Sets or Removes an extended style of a ListView control.</summary>
        ''' <param name="Lv">The ListView control.</param>
        ''' <param name="exstyle">One or more of the ListViewExtendedStyles to set or remove. Use the bitwise (Or) to combine more than one style at a time.</param>
        ''' <param name="setstyle">If set to True, the styles are set. If set to False, the styles are removed.</param>
        Private Sub SetListViewExtendedStyles(Lv As ListView, exstyle As ListViewExtendedStyles, setstyle As Boolean)
            SendMessageW(Lv.Handle, LVM_SETEXTENDEDSTYLE, exstyle, If(setstyle, exstyle, 0))
        End Sub
    End Class
    
    Public Enum ListViewExtendedStyles As Integer
        GridLines = &H1
        SubItemImages = &H2
        CheckBoxes = &H4
        TrackSelect = &H8
        HeaderDragDrop = &H10
        FullRowSelect = &H20
        OneClickActivate = &H40
        TwoClickActivate = &H80
        FlatsB = &H100
        Regional = &H200
        InfoTip = &H400
        UnderlineHot = &H800
        UnderlineCold = &H1000
        MultilWorkAreas = &H2000
        LabelTip = &H4000
        BorderSelect = &H8000
        DoubleBuffer = &H10000
        HideLabels = &H20000
        SingleRow = &H40000
        SnapToGrid = &H80000
        SimpleSelect = &H100000
        AutoCheckSelect = &H8000000
    End Enum


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Wednesday, January 10, 2018 7:48 PM
    • Marked as answer by CitySoft Thursday, January 11, 2018 12:48 AM
    Wednesday, January 10, 2018 7:47 PM
  •  Well,  i am still not sure exactly how you want everything to work in the ListView but,  perhaps you can just create your own small ListView class to your project so that you can detect the mouse button messages before the ListView processes them.  This way you can deny all clicks that are not on the Label part of the ListViewItems as shown below.

     Here is a small example you can try in a new Form project to see if it will work the way you want.  Create a new form project and add the code below.  Then run/debug the application or Build the application from the Build menu.  After that,  you will find the ListViewEx control in the toolbox. Add one to the form.

    Public Class Form1
        'The empty Form1 Class....
    End Class
    
    
    Public Class ListViewEx
        Inherits ListView
    
        Private Const WM_LBUTTONDOWN As Integer = &H201
        Private Const WM_RBUTTONDOWN As Integer = &H204
    
        Public Property MultiCheck As Boolean = False
    
        Protected Overrides Sub WndProc(ByRef m As Message)
            If m.Msg = WM_LBUTTONDOWN OrElse m.Msg = WM_RBUTTONDOWN Then
                Dim loc As Point = Me.PointToClient(MousePosition)
                If Not Me.HitTest(loc).Location = ListViewHitTestLocations.Label Then
                    m.Result = CType(0, IntPtr)
                    Return
                Else
                    Dim lvi As ListViewItem = Me.GetItemAt(loc.X, loc.Y)
                    If lvi IsNot Nothing Then
                        If MultiCheck Then
                            lvi.Checked = Not lvi.Checked
                        Else
                            For Each ci As ListViewItem In Me.CheckedItems
                                ci.Checked = False
                            Next
                            lvi.Checked = True
                        End If
                    End If
                End If
            End If
            MyBase.WndProc(m)
        End Sub
    End Class
    
     

     After adding the ListBoxEx control to the form you can add the code below to the empty Form1 class.  Then you can run/debug the application again and see how it works.

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ListViewEx1.CheckBoxes = True
            ListViewEx1.MultiCheck = True 'you can set the MultiCheck property True or False when needed
            For i As Integer = 0 To 4
                ListViewEx1.Items.Add("Item " & i.ToString)
            Next
        End Sub
    
    End Class
    
    

     

     I wont be able to get back to you and answer any further questions until later.  8)


    If you say it can`t be done then i`ll try it

    • Marked as answer by CitySoft Thursday, January 11, 2018 6:43 PM
    Thursday, January 11, 2018 11:18 AM

All replies

  • I want to make listview check the item if selected by mouse

      If all you want to do is to check the item(s) that are selected,  you can just use the ListView's ItemSelectionChanged event like shown in the example below.

     However,  this example can be modified to work other ways too.  For example,  if you don't want the items to be un-checked when they are un-selected,  or whatever.
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ListView1.CheckBoxes = True
            For i As Integer = 0 To 4
                ListView1.Items.Add("Item " & i.ToString)
            Next
        End Sub
    
        Private Sub ListView1_ItemSelectionChanged(sender As Object, e As ListViewItemSelectionChangedEventArgs) Handles ListView1.ItemSelectionChanged
            e.Item.Checked = e.IsSelected 'if the item is selected it is checked. If it is un-selected, it is un-checked
        End Sub
    End Class
    
    

     

     

     Also,  if you only what the items to be checked or un-checked if the mouse clicks them and not when the keyboard is used to iterate through the items,  then you could do something similar to this...

    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ListView1.CheckBoxes = True
            For i As Integer = 0 To 4
                ListView1.Items.Add("Item " & i.ToString)
            Next
        End Sub

        Private Sub ListView1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
            Dim lvi As ListViewItem = ListView1.GetItemAt(e.X, e.Y)
            If lvi IsNot Nothing Then lvi.Checked = True
            'If lvi IsNot Nothing Then lvi.Checked = Not lvi.Checked  'use this line instead,  if you want it to check/un-check when mouse clicks the item
        End Sub
    End Class

     I am sure if you experiment a little with these methods you could get it to do what you want without setting the extended styles.  8)


    If you say it can`t be done then i`ll try it

    • Marked as answer by CitySoft Thursday, January 11, 2018 12:48 AM
    Wednesday, January 10, 2018 6:40 PM
  •  Just in case you actually have the need to set other extended styles of the ListView that are not available through the .Net Listview control Properties,  you can check the below example which sets or removes the specified extended styles of a ListView.

     If you read the msdn documents for the LVM_SETEXTENDEDLISTVIEWSTYLE message,  you will see that it is not required to get the extended styles in order to set or remove the styles.  You can see that they use the wParam and lParam to specify the extended style and to determine if they should be set or removed. 

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        Private Const LVM_SETEXTENDEDSTYLE As Integer = &H1036
    
        <DllImport("user32.dll", EntryPoint:="SendMessageW")>
        Private Shared Function SendMessageW(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
        End Function
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'sets the AutoCheckSelect and CheckBoxes extended styles for ListView1 in one call to the SetListViewExtendedStyles
            SetListViewExtendedStyles(ListView1, ListViewExtendedStyles.AutoCheckSelect Or ListViewExtendedStyles.CheckBoxes, True)
            For i As Integer = 0 To 4
                ListView1.Items.Add("Item " & i.ToString)
            Next
        End Sub
    
        ''' <summary>Sets or Removes an extended style of a ListView control.</summary>
        ''' <param name="Lv">The ListView control.</param>
        ''' <param name="exstyle">One or more of the ListViewExtendedStyles to set or remove. Use the bitwise (Or) to combine more than one style at a time.</param>
        ''' <param name="setstyle">If set to True, the styles are set. If set to False, the styles are removed.</param>
        Private Sub SetListViewExtendedStyles(Lv As ListView, exstyle As ListViewExtendedStyles, setstyle As Boolean)
            SendMessageW(Lv.Handle, LVM_SETEXTENDEDSTYLE, exstyle, If(setstyle, exstyle, 0))
        End Sub
    End Class
    
    Public Enum ListViewExtendedStyles As Integer
        GridLines = &H1
        SubItemImages = &H2
        CheckBoxes = &H4
        TrackSelect = &H8
        HeaderDragDrop = &H10
        FullRowSelect = &H20
        OneClickActivate = &H40
        TwoClickActivate = &H80
        FlatsB = &H100
        Regional = &H200
        InfoTip = &H400
        UnderlineHot = &H800
        UnderlineCold = &H1000
        MultilWorkAreas = &H2000
        LabelTip = &H4000
        BorderSelect = &H8000
        DoubleBuffer = &H10000
        HideLabels = &H20000
        SingleRow = &H40000
        SnapToGrid = &H80000
        SimpleSelect = &H100000
        AutoCheckSelect = &H8000000
    End Enum


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Wednesday, January 10, 2018 7:48 PM
    • Marked as answer by CitySoft Thursday, January 11, 2018 12:48 AM
    Wednesday, January 10, 2018 7:47 PM
  • You are the best ...thank you 

    I am already need all of your answers

    • Edited by CitySoft Thursday, January 11, 2018 1:02 AM
    Thursday, January 11, 2018 12:49 AM
  • You are the best ...thank you 

     I wouldn't say that but,  you're welcome.  8)

    If you say it can`t be done then i`ll try it

    Thursday, January 11, 2018 12:55 AM
  • Sorry again

    It seems because I use a lot of workarounds some time if forget to deal with the basics :D

    here is the code that I use to check the item if clicked by mouse

    Private Sub InnerListView_MouseClick(sender As Object, e As MouseEventArgs) Handles InnerListView.MouseUp
                    If e.Button = MouseButtons.Left Then
                        Dim currentItem As ListViewItem = InnerListView.GetItemAt(e.X, e.Y)
                        If currentItem IsNot Nothing Then
                            If MultiCheck = False Then
                                For Each item As ListViewItem In InnerListView.Items
                                    If item Is currentItem Then
                                        item.Checked = True
                                    Else
                                        item.Checked = False
                                    End If
                                Next
                            Else
                                currentItem.Checked = Not currentItem.Checked
                            End If
                        End If
                    End If
                End Sub


    It works fine for me
    But there is one problem
    when I click by mouse on the checkbox itself the checkbox make the item checked and my code reverse the check again

    so what I want  -which is not the header of the question -My Mistake :( -
    is to disable the original behavior of the listview witch is ( Checking the item by mouse when click the chekbox) or at least disable Checking the item by On click

    so I tried your
    SetListViewExtendedStyles .. but it also didn't disable or enable I tried with deferent styles like GridLines but also didn't draw the grid so maybe I did something wrong 

    Do I have to mention that this listview is inside a ContextMenuStrip ?

    Friend Class FilterCheckList

    Inherits ToolStripControlHost Private WithEvents InnerListView As ListView Public Sub New() MyBase.New(New ListView()) InnerListView = MyBase.Control InnerListView.Columns.Add("aa", 600) InnerListView.View = View.Details InnerListView.RightToLeftLayout = True SetListViewExtendedStyles(InnerListView, ListViewExtendedStyles.GridLines Or ListViewExtendedStyles.CheckBoxes, True) SetListViewExtendedStyles(InnerListView, ListViewExtendedStyles.AutoCheckSelect , False) End Sub End Class 

    Edit : I tried it with normal listview didn't work also >>> And I don't want use checklistbox I want a listview 







     
    • Edited by CitySoft Thursday, January 11, 2018 7:37 AM
    Thursday, January 11, 2018 7:22 AM
  • coz you are patience and you used to post a GIF :)
    Thursday, January 11, 2018 7:39 AM
  •  Well,  i am still not sure exactly how you want everything to work in the ListView but,  perhaps you can just create your own small ListView class to your project so that you can detect the mouse button messages before the ListView processes them.  This way you can deny all clicks that are not on the Label part of the ListViewItems as shown below.

     Here is a small example you can try in a new Form project to see if it will work the way you want.  Create a new form project and add the code below.  Then run/debug the application or Build the application from the Build menu.  After that,  you will find the ListViewEx control in the toolbox. Add one to the form.

    Public Class Form1
        'The empty Form1 Class....
    End Class
    
    
    Public Class ListViewEx
        Inherits ListView
    
        Private Const WM_LBUTTONDOWN As Integer = &H201
        Private Const WM_RBUTTONDOWN As Integer = &H204
    
        Public Property MultiCheck As Boolean = False
    
        Protected Overrides Sub WndProc(ByRef m As Message)
            If m.Msg = WM_LBUTTONDOWN OrElse m.Msg = WM_RBUTTONDOWN Then
                Dim loc As Point = Me.PointToClient(MousePosition)
                If Not Me.HitTest(loc).Location = ListViewHitTestLocations.Label Then
                    m.Result = CType(0, IntPtr)
                    Return
                Else
                    Dim lvi As ListViewItem = Me.GetItemAt(loc.X, loc.Y)
                    If lvi IsNot Nothing Then
                        If MultiCheck Then
                            lvi.Checked = Not lvi.Checked
                        Else
                            For Each ci As ListViewItem In Me.CheckedItems
                                ci.Checked = False
                            Next
                            lvi.Checked = True
                        End If
                    End If
                End If
            End If
            MyBase.WndProc(m)
        End Sub
    End Class
    
     

     After adding the ListBoxEx control to the form you can add the code below to the empty Form1 class.  Then you can run/debug the application again and see how it works.

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ListViewEx1.CheckBoxes = True
            ListViewEx1.MultiCheck = True 'you can set the MultiCheck property True or False when needed
            For i As Integer = 0 To 4
                ListViewEx1.Items.Add("Item " & i.ToString)
            Next
        End Sub
    
    End Class
    
    

     

     I wont be able to get back to you and answer any further questions until later.  8)


    If you say it can`t be done then i`ll try it

    • Marked as answer by CitySoft Thursday, January 11, 2018 6:43 PM
    Thursday, January 11, 2018 11:18 AM
  • Thank you 

    with some changes is did what I need

    Protected Overrides Sub WndProc(ByRef m As Message)
                        If m.Msg = WM_LBUTTONDOWN Then
                            Dim loc As Point = Me.PointToClient(MousePosition)
                            Dim lvi As ListViewItem = Me.GetItemAt(loc.X, loc.Y)
                            If lvi IsNot Nothing Then
                                If MultiCheck Then
                                    lvi.Checked = Not lvi.Checked
                                Else
                                    For Each ci As ListViewItem In Me.CheckedItems
                                        ci.Checked = False
                                    Next
                                    lvi.Checked = True
                                End If
                            End If
                            If Not Me.HitTest(loc).Location = ListViewHitTestLocations.Label Then
                                m.Result = CType(0, IntPtr)
                                Return
                            End If
                        End If
                        MyBase.WndProc(m)
                    End Sub




    thank your for you patience 

    Thursday, January 11, 2018 6:42 PM
  •  You're welcome.  8)

    If you say it can`t be done then i`ll try it

    Thursday, January 11, 2018 6:51 PM