|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Listview QuestionI 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. 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. > 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. > 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. >> > > 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. >>> >> >> > > 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. >>>> >>> >>> >> >> > > |
|||||||||||||||||||||||