Parker Zhang [MSFT]
2003-08-12 06:43:47 UTC
Hello,
There are no such a function to get the subitem. You should it manually.
1. Create a new Windows Application project using Visual Basic .NET.
2. Add a Listview Control, Textbox, and Command button to the form
(Listview1, Textbox1, and Button1 respectively).
3. Set the View property of the Listview control to "Details".
4. Add the following code to the form class.
5. Build the project and run it. Note that the Listview control populates
with data.
6. Click on individual "cells" within the Listview and note that the value
you clicked on displays in the textbox.
7. Modify the value in the textbox, and click the command button. Note that
the value from the textbox replaces the last Listview Subitem you clicked
on.
---------------------------------
Imports System.Runtime.InteropServices
<<<Windows Form Generated Code>>>
Const LVM_FIRST As Integer = &H1000
Const LVM_GETSUBITEMRECT As Integer = (LVM_FIRST + 56)
Const LVIR_BOUNDS As Integer = 0
Const LVIR_ICON As Integer = 1
<StructLayout(LayoutKind.Sequential)> Structure RECT
Dim left As Integer
Dim top As Integer
Dim right As Integer
Dim bottom As Integer
End Structure
<DllImport("user32.dll")> _
Private Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Integer, _
ByVal wParam As Integer, _
ByRef lParam As RECT) As Integer
End Function
Dim arrData(2, 2) As String
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'Fill the array with some data
arrData(0, 0) = "Charlotte"
arrData(0, 1) = "NC"
arrData(0, 2) = "(980) 555-5555"
arrData(1, 0) = "Dallas"
arrData(1, 1) = "TX"
arrData(1, 2) = "(917) 333-3333"
arrData(2, 0) = "Redmond"
arrData(2, 1) = "WA"
arrData(2, 2) = "(425) 888-8888"
SetupListView()
End Sub
Sub SetupListView()
Dim lv As ListView = ListView1
Dim lvitem As ListViewItem
Dim ch As ColumnHeader
Dim lvsitem As ListViewItem.ListViewSubItem
Dim intLVItemCounter As Integer
Dim intSubItemCounter As Integer
'Clear the Listview, enable GridLines and FullRowSelect
lv.Clear()
lv.GridLines = True
lv.FullRowSelect = True
'Loop through the array from element 1 of the second dimension
'to create ListViewItems (rows)
For intLVItemCounter = 0 To arrData.GetUpperBound(0)
'Create a new ListViewItem, and set its Text to
'the appropriate value from the array
lvitem = New ListViewItem()
lvitem.Text = arrData(intLVItemCounter, 0)
'Loop through the array elements of the first dimension
'to create SubItems.
For intSubItemCounter = 1 To arrData.GetUpperBound(1)
'Add a SubItem with the text from the appropriate location in the
array
lvitem.SubItems.Add(arrData(intLVItemCounter, intSubItemCounter))
Next
'Add the ListViewItem to the control
lv.Items.Add(lvitem)
Next
'Add columns to the control
AddColumns("City")
AddColumns("State")
AddColumns("Telephone")
For Each ch In lv.Columns
ch.Width = -2
Next
End Sub
Sub AddColumns(ByVal Text As String)
Dim lv As ListView = ListView1
Dim ch As ColumnHeader
ch = New ColumnHeader()
ch.Text = Text
lv.Columns.Add(ch)
End Sub
Private Sub ListView1_MouseUp(ByVal sender As Object, _
ByVal e As
System.Windows.Forms.MouseEventArgs) _
Handles ListView1.MouseUp
Dim myrect As RECT
Dim lvitem As ListViewItem
Dim intLVSubItemIndex As Integer
Dim LVSubItem As ListViewItem.ListViewSubItem
Dim intSendMessage As Integer
'Get the ListViewItem that was clicked on. This gives us the "Row"
lvitem = ListView1.FocusedItem
'Loop through the SubItems for this ListViewItem
For intLVSubItemIndex = 1 To lvitem.SubItems.Count - 1
'Reference the current SubItem
LVSubItem = lvitem.SubItems(intLVSubItemIndex)
'Create a new RECT structure and initialize its Top member to
'the index number of the SubItem we want to check. Initialize the
'Left member to LVIR_BOUNDS to indicate we want to get its rectangle
'bounds
myrect = New RECT()
myrect.top = intLVSubItemIndex
myrect.left = LVIR_BOUNDS
'Call the SendMessage API and pass it the handle to our Listview.
'Pass in the LVM_GETSUBITEMRECT message to indicate we want to
retrieve
'information about the SubItem rectangle. Pass in the index of our
ListViewItem
'and finally our RECT structure. If successful, the API will fill our
RECT structure
'with the bounds of the rectangle being used by the SubItem
intSendMessage = SendMessage(ListView1.Handle, LVM_GETSUBITEMRECT,
lvitem.Index, myrect)
'Check the mouse's X coordinate and compare it to the Left member of
the structure
'If the X coord is less than the rectangle's Left member, the user
clicked in the
'first column (which represents the ListviewItem). If the X coord is
greater than
'rectangle's Left member and less than its Right member, we know the
user clicked
'within this region.
If e.X < myrect.left Then
LVSubItem = lvitem.SubItems(0)
intLVSubItemIndex = 0
Exit For
ElseIf e.X >= myrect.left And e.X <= myrect.right Then
Exit For
Else
LVSubItem = Nothing
End If
Next
'If both the SubItem and ListViewItem objects are valid,
'Set the value of the Tag and Text properties respectively.
'I set the Tag property of the TextBox to the index, so that later
'on we know which column to update
If Not IsNothing(LVSubItem) And Not IsNothing(lvitem) Then
TextBox1.Tag = intLVSubItemIndex
TextBox1.Text = LVSubItem.Text
Else
TextBox1.Text = ""
TextBox1.Tag = ""
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim lvitem As ListViewItem = ListView1.FocusedItem
Dim lvsitem As ListViewItem.ListViewSubItem
Dim i As Integer = CType(TextBox1.Tag, Integer)
'Update the ListView from the data in the textbox. We use the Tag
'property of the textbox to find out which subitem to update
ListView1.Items(lvitem.Index).SubItems(i).Text = TextBox1.Text
'Update the array from the data in the textbox
arrData(lvitem.Index, i) = TextBox1.Text
End Sub
--
Parker Zhang
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
There are no such a function to get the subitem. You should it manually.
1. Create a new Windows Application project using Visual Basic .NET.
2. Add a Listview Control, Textbox, and Command button to the form
(Listview1, Textbox1, and Button1 respectively).
3. Set the View property of the Listview control to "Details".
4. Add the following code to the form class.
5. Build the project and run it. Note that the Listview control populates
with data.
6. Click on individual "cells" within the Listview and note that the value
you clicked on displays in the textbox.
7. Modify the value in the textbox, and click the command button. Note that
the value from the textbox replaces the last Listview Subitem you clicked
on.
---------------------------------
Imports System.Runtime.InteropServices
<<<Windows Form Generated Code>>>
Const LVM_FIRST As Integer = &H1000
Const LVM_GETSUBITEMRECT As Integer = (LVM_FIRST + 56)
Const LVIR_BOUNDS As Integer = 0
Const LVIR_ICON As Integer = 1
<StructLayout(LayoutKind.Sequential)> Structure RECT
Dim left As Integer
Dim top As Integer
Dim right As Integer
Dim bottom As Integer
End Structure
<DllImport("user32.dll")> _
Private Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Integer, _
ByVal wParam As Integer, _
ByRef lParam As RECT) As Integer
End Function
Dim arrData(2, 2) As String
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'Fill the array with some data
arrData(0, 0) = "Charlotte"
arrData(0, 1) = "NC"
arrData(0, 2) = "(980) 555-5555"
arrData(1, 0) = "Dallas"
arrData(1, 1) = "TX"
arrData(1, 2) = "(917) 333-3333"
arrData(2, 0) = "Redmond"
arrData(2, 1) = "WA"
arrData(2, 2) = "(425) 888-8888"
SetupListView()
End Sub
Sub SetupListView()
Dim lv As ListView = ListView1
Dim lvitem As ListViewItem
Dim ch As ColumnHeader
Dim lvsitem As ListViewItem.ListViewSubItem
Dim intLVItemCounter As Integer
Dim intSubItemCounter As Integer
'Clear the Listview, enable GridLines and FullRowSelect
lv.Clear()
lv.GridLines = True
lv.FullRowSelect = True
'Loop through the array from element 1 of the second dimension
'to create ListViewItems (rows)
For intLVItemCounter = 0 To arrData.GetUpperBound(0)
'Create a new ListViewItem, and set its Text to
'the appropriate value from the array
lvitem = New ListViewItem()
lvitem.Text = arrData(intLVItemCounter, 0)
'Loop through the array elements of the first dimension
'to create SubItems.
For intSubItemCounter = 1 To arrData.GetUpperBound(1)
'Add a SubItem with the text from the appropriate location in the
array
lvitem.SubItems.Add(arrData(intLVItemCounter, intSubItemCounter))
Next
'Add the ListViewItem to the control
lv.Items.Add(lvitem)
Next
'Add columns to the control
AddColumns("City")
AddColumns("State")
AddColumns("Telephone")
For Each ch In lv.Columns
ch.Width = -2
Next
End Sub
Sub AddColumns(ByVal Text As String)
Dim lv As ListView = ListView1
Dim ch As ColumnHeader
ch = New ColumnHeader()
ch.Text = Text
lv.Columns.Add(ch)
End Sub
Private Sub ListView1_MouseUp(ByVal sender As Object, _
ByVal e As
System.Windows.Forms.MouseEventArgs) _
Handles ListView1.MouseUp
Dim myrect As RECT
Dim lvitem As ListViewItem
Dim intLVSubItemIndex As Integer
Dim LVSubItem As ListViewItem.ListViewSubItem
Dim intSendMessage As Integer
'Get the ListViewItem that was clicked on. This gives us the "Row"
lvitem = ListView1.FocusedItem
'Loop through the SubItems for this ListViewItem
For intLVSubItemIndex = 1 To lvitem.SubItems.Count - 1
'Reference the current SubItem
LVSubItem = lvitem.SubItems(intLVSubItemIndex)
'Create a new RECT structure and initialize its Top member to
'the index number of the SubItem we want to check. Initialize the
'Left member to LVIR_BOUNDS to indicate we want to get its rectangle
'bounds
myrect = New RECT()
myrect.top = intLVSubItemIndex
myrect.left = LVIR_BOUNDS
'Call the SendMessage API and pass it the handle to our Listview.
'Pass in the LVM_GETSUBITEMRECT message to indicate we want to
retrieve
'information about the SubItem rectangle. Pass in the index of our
ListViewItem
'and finally our RECT structure. If successful, the API will fill our
RECT structure
'with the bounds of the rectangle being used by the SubItem
intSendMessage = SendMessage(ListView1.Handle, LVM_GETSUBITEMRECT,
lvitem.Index, myrect)
'Check the mouse's X coordinate and compare it to the Left member of
the structure
'If the X coord is less than the rectangle's Left member, the user
clicked in the
'first column (which represents the ListviewItem). If the X coord is
greater than
'rectangle's Left member and less than its Right member, we know the
user clicked
'within this region.
If e.X < myrect.left Then
LVSubItem = lvitem.SubItems(0)
intLVSubItemIndex = 0
Exit For
ElseIf e.X >= myrect.left And e.X <= myrect.right Then
Exit For
Else
LVSubItem = Nothing
End If
Next
'If both the SubItem and ListViewItem objects are valid,
'Set the value of the Tag and Text properties respectively.
'I set the Tag property of the TextBox to the index, so that later
'on we know which column to update
If Not IsNothing(LVSubItem) And Not IsNothing(lvitem) Then
TextBox1.Tag = intLVSubItemIndex
TextBox1.Text = LVSubItem.Text
Else
TextBox1.Text = ""
TextBox1.Tag = ""
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim lvitem As ListViewItem = ListView1.FocusedItem
Dim lvsitem As ListViewItem.ListViewSubItem
Dim i As Integer = CType(TextBox1.Tag, Integer)
'Update the ListView from the data in the textbox. We use the Tag
'property of the textbox to find out which subitem to update
ListView1.Items(lvitem.Index).SubItems(i).Text = TextBox1.Text
'Update the array from the data in the textbox
arrData(lvitem.Index, i) = TextBox1.Text
End Sub
--
Parker Zhang
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.