Home All Groups Group Topic Archive Search About
Author
20 Mar 2006 12:27 PM
Martin Horn
Hi all,

I want to implement a listview with editable subitems and I assume the
easiest way is to overlay a textbox over the item to be edited.

With this in mind I have come up with:

Using fullrowselect=true in the listview

Private Sub ListView1_ItemSelectionChanged(ByVal sender As Object, _
ByVal e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs) _
Handles ListView1.ItemSelectionChanged
    Dim t As New TextBox
    Me.Controls.Add(t)
    t.Location = e.Item.Position
    t.BringToFront()
End Sub

Unfortunately item.position only enables me to get the position of the first
column. How can I obtain the x position of the subitem that was clicked.

I have searched google, but the only examples I can find are in C++ which I
can't make any sense of.

Thanks,

Martin.

Author
20 Mar 2006 2:03 PM
Martin Horn
I have found this VB6 example, but I can't figure out how to convert it to
..net, can anyone help me.

Thanks

'Declarations:
Private Type lvwItemClick
    x As Long
    y As Long
    Flgs As Long
    Itm As Long
    SubItm As Long
End Type

Private Declare Function SendMessage _
    Lib "user32" Alias "SendMessageA" ( _
        ByVal hwnd As Long, _
        ByVal lMsg As Long, _
        ByVal wParam As Long, _
        lParam As Any) As Long

Dim lvwClick As lvwItemClick

Private Sub ListView1_MouseDown(Button As Integer, _
        Shift As Integer, x As Single, y As Single)

    lvwClick .x = x / Screen.TwipsPerPixelX
    lvwClick .y = y / Screen.TwipsPerPixelY

    SendMessage ListView1.hwnd, 4153, 0, lvwClick

    If Button = vbRightButton And lvwClick .Itm = 2 And lvwClick .SubItm = 1
Then _
    PopupMenu mnuTest 'poppup menu mnuTest for click on Item 3, SubItem 1.

End Sub


Show quoteHide quote
"Martin Horn" <mvh***@theinternet.com> wrote in message
news:GcxTf.7052$uT3.6210@newsfe7-win.ntli.net...
> Hi all,
>
> I want to implement a listview with editable subitems and I assume the
> easiest way is to overlay a textbox over the item to be edited.
>
> With this in mind I have come up with:
>
> Using fullrowselect=true in the listview
>
> Private Sub ListView1_ItemSelectionChanged(ByVal sender As Object, _
> ByVal e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs) _
> Handles ListView1.ItemSelectionChanged
>    Dim t As New TextBox
>    Me.Controls.Add(t)
>    t.Location = e.Item.Position
>    t.BringToFront()
> End Sub
>
> Unfortunately item.position only enables me to get the position of the
> first column. How can I obtain the x position of the subitem that was
> clicked.
>
> I have searched google, but the only examples I can find are in C++ which
> I can't make any sense of.
>
> Thanks,
>
> Martin.
>
Author
20 Mar 2006 11:00 PM
Martin
I'm working on the same thing... Not yet complete, but it's getting there.

Private Sub lstRules_MouseUp(ByVal sender As Object, ByVal e _
As System.Windows.Forms.MouseEventArgs) Handles lstRules.MouseUp
    Dim ThisItem As System.Windows.Forms.ListViewItem
    Dim NewBox As Control

    If Not (e.Button = Windows.Forms.MouseButtons.Left) Then Exit Sub

    ThisItem = lstRules.HitTest(e.X, e.Y).Item
    If ThisItem Is Nothing Then
        Exit Sub
    End If

    NewBox = New System.Windows.Forms.TextBox
    NewBox.Size = New System.Drawing.Size(lstRules.Columns(1).Width - 10,
12)
    NewBox.Text = KeyItem.ItemText
    NewBox.Location = New System.Drawing.Point(ThisItem.Position.X + _
                                     lstRules.Columns(0).Width + 2,
ThisItem.Position.Y + 1)

    Me.Controls.Add(NewBox)
    Me.NewBox.BringToFront
    AddHandler NewBox.LostFocus, AddressOf DestroyBox
    NewBox.Focus()
End Sub

Private Sub DestroyBox(ByVal sender As Object, ByVal e As System.EventArgs)
    If sender IsNot Nothing Then
        Me.Controls.Remove(sender)
        sender.Dispose()
    End If
End Sub

Work in progress: Moving the textbox when the user scrolls the Listview.
If you're interested I can post that bit tomorrow

Hth,
Martin


Show quoteHide quote
"Martin Horn" <mvh***@theinternet.com> wrote in message
news:GcxTf.7052$uT3.6210@newsfe7-win.ntli.net...
> Hi all,
>
> I want to implement a listview with editable subitems and I assume the
> easiest way is to overlay a textbox over the item to be edited.
>
> With this in mind I have come up with:
>
> Using fullrowselect=true in the listview
>
> Private Sub ListView1_ItemSelectionChanged(ByVal sender As Object, _
> ByVal e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs) _
> Handles ListView1.ItemSelectionChanged
>    Dim t As New TextBox
>    Me.Controls.Add(t)
>    t.Location = e.Item.Position
>    t.BringToFront()
> End Sub
>
> Unfortunately item.position only enables me to get the position of the
> first column. How can I obtain the x position of the subitem that was
> clicked.
>
> I have searched google, but the only examples I can find are in C++ which
> I can't make any sense of.
>
> Thanks,
>
> Martin.
>
Author
21 Mar 2006 2:01 AM
Martin Horn
Hi Martin,

I have come up with something similar myself, but I can't see how to easily
adapt it to work with scrolling of the listview, so I would definitely be
interested to see your solution.

Here is my version anyway, which retrieves the text from the any of the 6
subitems in my listview and fills the textbox with it when the user double
clicks the listview subitem.

Note: My example doesn't dynamically create the textbox and I have omitted
the code to remove the textbox.

Private Sub ListView1_MouseDoubleClick(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles ListView1.MouseDoubleClick
    Dim ItemX As ListViewItem
    ItemX = ListView1.GetItemAt(e.X, e.Y)
    If ItemX Is Nothing Then Exit Sub

    Dim col As Integer = GetColumnNumber(e.X)

    EditBox.Top = ItemX.Position.Y
    EditBox.Left = GetColumnX(e.X) + 2
    EditBox.Text = ListView1.SelectedItems(0).SubItems(col).Text
    EditBox.Width = ListView1.Columns(col).Width
    EditBox.BringToFront()
    EditBox.Focus()
End Sub

Private Function GetColumnNumber(ByVal MouseX As Integer) As Integer
    If MouseX < GetTotalWidth(0) Then Return -1
    If MouseX < GetTotalWidth(1) Then Return 0
    If MouseX < GetTotalWidth(2) Then Return 1
    If MouseX < GetTotalWidth(3) Then Return 2
    If MouseX < GetTotalWidth(4) Then Return 3
    If MouseX < GetTotalWidth(5) Then Return 4
    If MouseX < GetTotalWidth(6) Then Return 5
End Function

Private Function GetColumnX(ByVal MouseX As Integer) As Integer
    If MouseX < GetTotalWidth(0) Then Return 0
    If MouseX < GetTotalWidth(1) Then Return GetTotalWidth(0)
    If MouseX < GetTotalWidth(2) Then Return GetTotalWidth(1)
    If MouseX < GetTotalWidth(3) Then Return GetTotalWidth(2)
    If MouseX < GetTotalWidth(4) Then Return GetTotalWidth(3)
    If MouseX < GetTotalWidth(5) Then Return GetTotalWidth(4)
    If MouseX < GetTotalWidth(6) Then Return GetTotalWidth(5)
End Function

Private Function GetTotalWidth(ByVal Cols As Integer) As Integer
    Dim tot As Integer = 0
    For n As Integer = 0 To Cols - 1
        tot += ListView1.Columns(n).Width
    Next
    Return tot
End Function

Show quoteHide quote
"Martin" <x@y.com> wrote in message
news:excpgIHTGHA.4900@TK2MSFTNGP09.phx.gbl...
> I'm working on the same thing... Not yet complete, but it's getting there.
>
> Private Sub lstRules_MouseUp(ByVal sender As Object, ByVal e _
> As System.Windows.Forms.MouseEventArgs) Handles lstRules.MouseUp
>    Dim ThisItem As System.Windows.Forms.ListViewItem
>    Dim NewBox As Control
>
>    If Not (e.Button = Windows.Forms.MouseButtons.Left) Then Exit Sub
>
>    ThisItem = lstRules.HitTest(e.X, e.Y).Item
>    If ThisItem Is Nothing Then
>        Exit Sub
>    End If
>
>    NewBox = New System.Windows.Forms.TextBox
>    NewBox.Size = New System.Drawing.Size(lstRules.Columns(1).Width - 10,
> 12)
>    NewBox.Text = KeyItem.ItemText
>    NewBox.Location = New System.Drawing.Point(ThisItem.Position.X + _
>                                     lstRules.Columns(0).Width + 2,
> ThisItem.Position.Y + 1)
>
>    Me.Controls.Add(NewBox)
>    Me.NewBox.BringToFront
>    AddHandler NewBox.LostFocus, AddressOf DestroyBox
>    NewBox.Focus()
> End Sub
>
> Private Sub DestroyBox(ByVal sender As Object, ByVal e As
> System.EventArgs)
>    If sender IsNot Nothing Then
>        Me.Controls.Remove(sender)
>        sender.Dispose()
>    End If
> End Sub
>
> Work in progress: Moving the textbox when the user scrolls the Listview.
> If you're interested I can post that bit tomorrow
>
> Hth,
> Martin
>
>
> "Martin Horn" <mvh***@theinternet.com> wrote in message
> news:GcxTf.7052$uT3.6210@newsfe7-win.ntli.net...
>> Hi all,
>>
>> I want to implement a listview with editable subitems and I assume the
>> easiest way is to overlay a textbox over the item to be edited.
>>
>> With this in mind I have come up with:
>>
>> Using fullrowselect=true in the listview
>>
>> Private Sub ListView1_ItemSelectionChanged(ByVal sender As Object, _
>> ByVal e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs) _
>> Handles ListView1.ItemSelectionChanged
>>    Dim t As New TextBox
>>    Me.Controls.Add(t)
>>    t.Location = e.Item.Position
>>    t.BringToFront()
>> End Sub
>>
>> Unfortunately item.position only enables me to get the position of the
>> first column. How can I obtain the x position of the subitem that was
>> clicked.
>>
>> I have searched google, but the only examples I can find are in C++ which
>> I can't make any sense of.
>>
>> Thanks,
>>
>> Martin.
>>
>
>
Author
21 Mar 2006 6:40 AM
Martin
I have changed my objective a bit. Since detecting a scroll event in a
Listview requires me to subclass the Listview (MS simply forgot to raise a
scroll event, although it is built in the API) I am going to do it right.
I'm building a subclass of the Listview that allows any kind of control
(checkbox, combobox, datetimepicker, textbox) to be added as subitem.

If you're interested I will publish the code on my site when I'm done.


Show quoteHide quote
"Martin Horn" <mvh***@theinternet.com> schrieb im Newsbeitrag
news:a8JTf.2539$g76.1581@newsfe2-gui.ntli.net...
> Hi Martin,
>
> I have come up with something similar myself, but I can't see how to
> easily adapt it to work with scrolling of the listview, so I would
> definitely be interested to see your solution.
>
> Here is my version anyway, which retrieves the text from the any of the 6
> subitems in my listview and fills the textbox with it when the user double
> clicks the listview subitem.
>
> Note: My example doesn't dynamically create the textbox and I have omitted
> the code to remove the textbox.
>
> Private Sub ListView1_MouseDoubleClick(ByVal sender As Object, _
> ByVal e As System.Windows.Forms.MouseEventArgs) _
> Handles ListView1.MouseDoubleClick
>    Dim ItemX As ListViewItem
>    ItemX = ListView1.GetItemAt(e.X, e.Y)
>    If ItemX Is Nothing Then Exit Sub
>
>    Dim col As Integer = GetColumnNumber(e.X)
>
>    EditBox.Top = ItemX.Position.Y
>    EditBox.Left = GetColumnX(e.X) + 2
>    EditBox.Text = ListView1.SelectedItems(0).SubItems(col).Text
>    EditBox.Width = ListView1.Columns(col).Width
>    EditBox.BringToFront()
>    EditBox.Focus()
> End Sub
>
> Private Function GetColumnNumber(ByVal MouseX As Integer) As Integer
>    If MouseX < GetTotalWidth(0) Then Return -1
>    If MouseX < GetTotalWidth(1) Then Return 0
>    If MouseX < GetTotalWidth(2) Then Return 1
>    If MouseX < GetTotalWidth(3) Then Return 2
>    If MouseX < GetTotalWidth(4) Then Return 3
>    If MouseX < GetTotalWidth(5) Then Return 4
>    If MouseX < GetTotalWidth(6) Then Return 5
> End Function
>
> Private Function GetColumnX(ByVal MouseX As Integer) As Integer
>    If MouseX < GetTotalWidth(0) Then Return 0
>    If MouseX < GetTotalWidth(1) Then Return GetTotalWidth(0)
>    If MouseX < GetTotalWidth(2) Then Return GetTotalWidth(1)
>    If MouseX < GetTotalWidth(3) Then Return GetTotalWidth(2)
>    If MouseX < GetTotalWidth(4) Then Return GetTotalWidth(3)
>    If MouseX < GetTotalWidth(5) Then Return GetTotalWidth(4)
>    If MouseX < GetTotalWidth(6) Then Return GetTotalWidth(5)
> End Function
>
> Private Function GetTotalWidth(ByVal Cols As Integer) As Integer
>    Dim tot As Integer = 0
>    For n As Integer = 0 To Cols - 1
>        tot += ListView1.Columns(n).Width
>    Next
>    Return tot
> End Function
>
> "Martin" <x@y.com> wrote in message
> news:excpgIHTGHA.4900@TK2MSFTNGP09.phx.gbl...
>> I'm working on the same thing... Not yet complete, but it's getting
>> there.
>>
>> Private Sub lstRules_MouseUp(ByVal sender As Object, ByVal e _
>> As System.Windows.Forms.MouseEventArgs) Handles lstRules.MouseUp
>>    Dim ThisItem As System.Windows.Forms.ListViewItem
>>    Dim NewBox As Control
>>
>>    If Not (e.Button = Windows.Forms.MouseButtons.Left) Then Exit Sub
>>
>>    ThisItem = lstRules.HitTest(e.X, e.Y).Item
>>    If ThisItem Is Nothing Then
>>        Exit Sub
>>    End If
>>
>>    NewBox = New System.Windows.Forms.TextBox
>>    NewBox.Size = New System.Drawing.Size(lstRules.Columns(1).Width - 10,
>> 12)
>>    NewBox.Text = KeyItem.ItemText
>>    NewBox.Location = New System.Drawing.Point(ThisItem.Position.X + _
>>                                     lstRules.Columns(0).Width + 2,
>> ThisItem.Position.Y + 1)
>>
>>    Me.Controls.Add(NewBox)
>>    Me.NewBox.BringToFront
>>    AddHandler NewBox.LostFocus, AddressOf DestroyBox
>>    NewBox.Focus()
>> End Sub
>>
>> Private Sub DestroyBox(ByVal sender As Object, ByVal e As
>> System.EventArgs)
>>    If sender IsNot Nothing Then
>>        Me.Controls.Remove(sender)
>>        sender.Dispose()
>>    End If
>> End Sub
>>
>> Work in progress: Moving the textbox when the user scrolls the Listview.
>> If you're interested I can post that bit tomorrow
>>
>> Hth,
>> Martin
>>
>>
>> "Martin Horn" <mvh***@theinternet.com> wrote in message
>> news:GcxTf.7052$uT3.6210@newsfe7-win.ntli.net...
>>> Hi all,
>>>
>>> I want to implement a listview with editable subitems and I assume the
>>> easiest way is to overlay a textbox over the item to be edited.
>>>
>>> With this in mind I have come up with:
>>>
>>> Using fullrowselect=true in the listview
>>>
>>> Private Sub ListView1_ItemSelectionChanged(ByVal sender As Object, _
>>> ByVal e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs) _
>>> Handles ListView1.ItemSelectionChanged
>>>    Dim t As New TextBox
>>>    Me.Controls.Add(t)
>>>    t.Location = e.Item.Position
>>>    t.BringToFront()
>>> End Sub
>>>
>>> Unfortunately item.position only enables me to get the position of the
>>> first column. How can I obtain the x position of the subitem that was
>>> clicked.
>>>
>>> I have searched google, but the only examples I can find are in C++
>>> which I can't make any sense of.
>>>
>>> Thanks,
>>>
>>> Martin.
>>>
>>
>>
>
>
Author
21 Mar 2006 5:58 PM
Martin Horn
Although my solution works in the context in which I am using it, I am well
aware that it isn't very efficient and would be very interested in seeing
how you approach the problem, as I am a newbie programmer and what you are
suggesting is well beyond my capabilities at the moment.

If you want to email me the link to your site you can send it to
mvhorn@remove_this_bit.ntlworld.com or post it here instead.

Kind regards,

Martin.

Show quoteHide quote
"Martin" <x@y.com> wrote in message
news:%23TTbgJLTGHA.4952@TK2MSFTNGP09.phx.gbl...
>I have changed my objective a bit. Since detecting a scroll event in a
>Listview requires me to subclass the Listview (MS simply forgot to raise a
>scroll event, although it is built in the API) I am going to do it right.
>I'm building a subclass of the Listview that allows any kind of control
>(checkbox, combobox, datetimepicker, textbox) to be added as subitem.
>
> If you're interested I will publish the code on my site when I'm done.
>
>
> "Martin Horn" <mvh***@theinternet.com> schrieb im Newsbeitrag
> news:a8JTf.2539$g76.1581@newsfe2-gui.ntli.net...
>> Hi Martin,
>>
>> I have come up with something similar myself, but I can't see how to
>> easily adapt it to work with scrolling of the listview, so I would
>> definitely be interested to see your solution.
>>
>> Here is my version anyway, which retrieves the text from the any of the 6
>> subitems in my listview and fills the textbox with it when the user
>> double clicks the listview subitem.
>>
>> Note: My example doesn't dynamically create the textbox and I have
>> omitted the code to remove the textbox.
>>
>> Private Sub ListView1_MouseDoubleClick(ByVal sender As Object, _
>> ByVal e As System.Windows.Forms.MouseEventArgs) _
>> Handles ListView1.MouseDoubleClick
>>    Dim ItemX As ListViewItem
>>    ItemX = ListView1.GetItemAt(e.X, e.Y)
>>    If ItemX Is Nothing Then Exit Sub
>>
>>    Dim col As Integer = GetColumnNumber(e.X)
>>
>>    EditBox.Top = ItemX.Position.Y
>>    EditBox.Left = GetColumnX(e.X) + 2
>>    EditBox.Text = ListView1.SelectedItems(0).SubItems(col).Text
>>    EditBox.Width = ListView1.Columns(col).Width
>>    EditBox.BringToFront()
>>    EditBox.Focus()
>> End Sub
>>
>> Private Function GetColumnNumber(ByVal MouseX As Integer) As Integer
>>    If MouseX < GetTotalWidth(0) Then Return -1
>>    If MouseX < GetTotalWidth(1) Then Return 0
>>    If MouseX < GetTotalWidth(2) Then Return 1
>>    If MouseX < GetTotalWidth(3) Then Return 2
>>    If MouseX < GetTotalWidth(4) Then Return 3
>>    If MouseX < GetTotalWidth(5) Then Return 4
>>    If MouseX < GetTotalWidth(6) Then Return 5
>> End Function
>>
>> Private Function GetColumnX(ByVal MouseX As Integer) As Integer
>>    If MouseX < GetTotalWidth(0) Then Return 0
>>    If MouseX < GetTotalWidth(1) Then Return GetTotalWidth(0)
>>    If MouseX < GetTotalWidth(2) Then Return GetTotalWidth(1)
>>    If MouseX < GetTotalWidth(3) Then Return GetTotalWidth(2)
>>    If MouseX < GetTotalWidth(4) Then Return GetTotalWidth(3)
>>    If MouseX < GetTotalWidth(5) Then Return GetTotalWidth(4)
>>    If MouseX < GetTotalWidth(6) Then Return GetTotalWidth(5)
>> End Function
>>
>> Private Function GetTotalWidth(ByVal Cols As Integer) As Integer
>>    Dim tot As Integer = 0
>>    For n As Integer = 0 To Cols - 1
>>        tot += ListView1.Columns(n).Width
>>    Next
>>    Return tot
>> End Function
>>
>> "Martin" <x@y.com> wrote in message
>> news:excpgIHTGHA.4900@TK2MSFTNGP09.phx.gbl...
>>> I'm working on the same thing... Not yet complete, but it's getting
>>> there.
>>>
>>> Private Sub lstRules_MouseUp(ByVal sender As Object, ByVal e _
>>> As System.Windows.Forms.MouseEventArgs) Handles lstRules.MouseUp
>>>    Dim ThisItem As System.Windows.Forms.ListViewItem
>>>    Dim NewBox As Control
>>>
>>>    If Not (e.Button = Windows.Forms.MouseButtons.Left) Then Exit Sub
>>>
>>>    ThisItem = lstRules.HitTest(e.X, e.Y).Item
>>>    If ThisItem Is Nothing Then
>>>        Exit Sub
>>>    End If
>>>
>>>    NewBox = New System.Windows.Forms.TextBox
>>>    NewBox.Size = New System.Drawing.Size(lstRules.Columns(1).Width - 10,
>>> 12)
>>>    NewBox.Text = KeyItem.ItemText
>>>    NewBox.Location = New System.Drawing.Point(ThisItem.Position.X + _
>>>                                     lstRules.Columns(0).Width + 2,
>>> ThisItem.Position.Y + 1)
>>>
>>>    Me.Controls.Add(NewBox)
>>>    Me.NewBox.BringToFront
>>>    AddHandler NewBox.LostFocus, AddressOf DestroyBox
>>>    NewBox.Focus()
>>> End Sub
>>>
>>> Private Sub DestroyBox(ByVal sender As Object, ByVal e As
>>> System.EventArgs)
>>>    If sender IsNot Nothing Then
>>>        Me.Controls.Remove(sender)
>>>        sender.Dispose()
>>>    End If
>>> End Sub
>>>
>>> Work in progress: Moving the textbox when the user scrolls the Listview.
>>> If you're interested I can post that bit tomorrow
>>>
>>> Hth,
>>> Martin
>>>
>>>
>>> "Martin Horn" <mvh***@theinternet.com> wrote in message
>>> news:GcxTf.7052$uT3.6210@newsfe7-win.ntli.net...
>>>> Hi all,
>>>>
>>>> I want to implement a listview with editable subitems and I assume the
>>>> easiest way is to overlay a textbox over the item to be edited.
>>>>
>>>> With this in mind I have come up with:
>>>>
>>>> Using fullrowselect=true in the listview
>>>>
>>>> Private Sub ListView1_ItemSelectionChanged(ByVal sender As Object, _
>>>> ByVal e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs)
>>>> _
>>>> Handles ListView1.ItemSelectionChanged
>>>>    Dim t As New TextBox
>>>>    Me.Controls.Add(t)
>>>>    t.Location = e.Item.Position
>>>>    t.BringToFront()
>>>> End Sub
>>>>
>>>> Unfortunately item.position only enables me to get the position of the
>>>> first column. How can I obtain the x position of the subitem that was
>>>> clicked.
>>>>
>>>> I have searched google, but the only examples I can find are in C++
>>>> which I can't make any sense of.
>>>>
>>>> Thanks,
>>>>
>>>> Martin.
>>>>
>>>
>>>
>>
>>
>
>