Microsoft KB Archive/320342

= How to use a ComboBox control to edit data in a ListView control in Visual Basic 2005 or in Visual Basic .NET =

Article ID: 320342

Article Last Modified on 5/11/2007

-

APPLIES TO


 * Microsoft Visual Basic 2005
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition

-



This article was previously published under Q320342





For a Microsoft Visual C# 2005 and Microsoft Visual C# .NET version of this article, see 320344.



SUMMARY
This step-by-step article demonstrates how to use a ComboBox control to edit the data in a ListView control. This method replaces the standard text box approach of editing the data in a ListView control.

Description of the technique
By using the LabelEdit property of the ListView control, you can let the user edit the contents of the ListView control. To edit the data in the ListView control, you can use a standard text box. Occasionally, it is useful to have another control to edit the control. This article simulates how to use a ComboBox control to edit the data in a ListView when the ListView is in Details view.

When the user selects a row in the ListView, a calculation is performed to locate the bounding rectangle for the first column of the row that is clicked. That calculation takes into account that the column may not be visible or may not be fully visible when the row is clicked and when the ComboBox is sized and displayed appropriately.

In addition to positioning and sizing the ComboBox, this sample also watches for two messages on the ListView control: WM_VSCROLL and WM_HSCROLL. These messages occur whenever the user scrolls through the ListView control vertically or horizontally. Because the ComboBox is not physically part of the ListView control, the ComboBox does not automatically scroll with the ListView. Therefore, whenever either of these two messages occur, the ComboBox must be hidden. To watch for these messages, you create a custom UserControl class that inherits from the ListView class. In this custom control, the WndProc method is overridden to allow all messages to be checked for scrolling.

Create the inherited ListView control
 Start Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET. On the File menu, point to New, and then click Project. In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Windows Control Library under Templates.

Note In Visual Studio 2005, click Visual Basic instead of Visual Basic Projects.  Replace all the code in the UserControl class with the following code. Imports System Imports System.Collections Imports System.ComponentModel Imports System.Drawing Imports System.Data Imports System.Windows.Forms

Public Class MyListView Inherits System.Windows.Forms.ListView


 * 1) Region &quot; Windows Form Designer generated code &quot;

Public Sub New MyBase.New

'This call is required by the Windows Form Designer. InitializeComponent

'Add any initialization after the InitializeComponent call

End Sub

'UserControl1 overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose End If       End If        MyBase.Dispose(disposing) End Sub

'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor.  Private Sub InitializeComponent components = New System.ComponentModel.Container End Sub


 * 1) End Region

Private Const WM_HSCROLL As Integer = &H114 Private Const WM_VSCROLL As Integer = &H115

Protected Overrides Sub WndProc(ByRef msg As Message) ' Look for the WM_VSCROLL or the WM_HSCROLL messages. If ((msg.Msg = WM_VSCROLL) Or (msg.Msg = WM_HSCROLL)) Then ' Move focus to the ListView to cause ComboBox to lose focus. Me.Focus End If

' Pass message to default handler. MyBase.WndProc(msg) End Sub End Class  Save and then build the project.</ol>

Create the sample application
<ol> Follow these steps to create a Windows Application in Visual Basic 2005 or in Visual Basic .NET: <ol style="list-style-type: lower-alpha;"> On the File menu, point to New, and then click Project.</li> In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Windows Application under Templates. By default, Form1 is created.

Note In Visual Studio 2005, click Visual Basic instead of Visual Basic Projects.

Note You must change the code in Visual Basic 2005. By default, Visual Basic creates two files for the project when you create a Windows Forms project. If the form is named Form1, the two files that represent the form are named Form1.vb and Form1.Designer.vb. You write the code in the Form1.vb file. The Windows Forms Designer writes the code in the Form1.Designer.vb file. The Windows Forms Designer uses the partial keyword to divide the implementation of Form1 into two separate files. This behavior prevents the designer-generated code from being interspersed with your code.

For more information about the new Visual Basic 2005 language enhancements, visit the following Microsoft Developer Network (MSDN) Web site:

http://msdn2.microsoft.com/en-us/library/ms379584(vs.80).aspx

For more information about partial classes and the Windows Forms Designer, visit the following MSDN Web site:

http://msdn2.microsoft.com/en-us/library/ms171843.aspx

</li></ol> </li> Follow these steps to add the control that you created in the &quot;Create the inherited ListView control&quot; section to your Windows application: <ol style="list-style-type: lower-alpha;"> On the Tools menu, click Customize Toolbox.</li> On the .NET Framework Components tab, click Browse.</li> In the Open dialog box, locate the control that you created in the &quot;Create the inherited ListView control&quot; section, and then click Open. This adds this control to the toolbox so that you can use the control similarly to any other control.</li> Drag MyListView from the General section of the toolbox to Form1.</li></ol> </li> Drag a ComboBox control from the Windows Forms section of the toolbox to Form1.</li> In the Properties window of ComboBox, change the Name property to cbListViewCombo, and then set the Visible property to False.</li>  Add the following code to the class of Form1 before the &quot;Windows Form Designer generated code&quot; section: Private lvItem As ListViewItem </li>  Add the following code to the Load event of Form1. ' Add a few items to the combo box list. Me.cbListViewCombo.Items.Add(&quot;NC&quot;) Me.cbListViewCombo.Items.Add(&quot;WA&quot;)

' Set view of ListView to Details. Me.MyListView1.View = View.Details

' Turn on full row select. Me.MyListView1.FullRowSelect = True

' Add some data to the ListView. Dim columnheader As ColumnHeader Dim lviewitem As ListViewItem

' Create sample ListView data. lviewitem = New ListViewItem(&quot;NC&quot;) lviewitem.SubItems.Add(&quot;North Carolina&quot;) Me.MyListView1.Items.Add(lviewitem)

lviewitem = New ListViewItem(&quot;WA&quot;) lviewitem.SubItems.Add(&quot;Washington&quot;) Me.MyListView1.Items.Add(lviewitem)

' Create column headers for the data. columnheader = New ColumnHeader columnheader.Text = &quot;State Abbr.&quot; Me.MyListView1.Columns.Add(columnheader)

columnheader = New ColumnHeader columnheader.Text = &quot;State&quot; Me.MyListView1.Columns.Add(columnheader)

' Loop through and size each column header to fit the column header text. Dim ch As ColumnHeader

For Each ch In Me.MyListView1.Columns ch.Width = -2 Next </li>  Add the following code to the SelectedValueChanged event of the ComboBox control. ' Set text of ListView item to match the ComboBox. lvItem.Text = Me.cbListViewCombo.Text

' Hide the ComboBox. Me.cbListViewCombo.Visible = False </li>  Add the following code to the Leave event of the ComboBox control. ' Set text of ListView item to match the ComboBox. lvItem.Text = Me.cbListViewCombo.Text

' Hide the ComboBox. Me.cbListViewCombo.Visible = False </li>  Add the following code to the KeyPress event of the ComboBox control. ' Verify that the user presses ESC. Select Case (e.KeyChar) Case ChrW(CType(Keys.Escape, Integer)) ' Reset the original text value, and then hide the ComboBox. Me.cbListViewCombo.Text = lvItem.Text Me.cbListViewCombo.Visible = False

Case ChrW(CType(Keys.Enter, Integer)) ' Hide the ComboBox. Me.cbListViewCombo.Visible = False End Select </li>  Add the following code to the MouseUp event of myListView1. ' Get the item on the row that is clicked. lvItem = Me.MyListView1.GetItemAt(e.X, e.Y)

' Make sure that an item is clicked. If Not (lvItem Is Nothing) Then ' Get the bounds of the item that is clicked. Dim ClickedItem As Rectangle = lvItem.Bounds

' Verify that the column is completely scrolled off to the left. If ((ClickedItem.Left + Me.MyListView1.Columns(0).Width) < 0) Then ' If the cell is out of view to the left, do nothing. Return

' Verify that the column is partially scrolled off to the left. ElseIf (ClickedItem.Left < 0) Then ' Determine if column extends beyond right side of ListView. If ((ClickedItem.Left + Me.MyListView1.Columns(0).Width) > Me.MyListView1.Width) Then ' Set width of column to match width of ListView. ClickedItem.Width = Me.MyListView1.Width ClickedItem.X = 0 Else ' Right side of cell is in view. ClickedItem.Width = Me.MyListView1.Columns(0).Width + ClickedItem.Left ClickedItem.X = 2 End If

ElseIf (Me.MyListView1.Columns(0).Width > Me.MyListView1.Width) Then ClickedItem.Width = Me.MyListView1.Width Else ClickedItem.Width = Me.MyListView1.Columns(0).Width ClickedItem.X = 2 End If

' Adjust the top to account for the location of the ListView. ClickedItem.Y += Me.MyListView1.Top ClickedItem.X += Me.MyListView1.Left

' Assign calculated bounds to the ComboBox. Me.cbListViewCombo.Bounds = ClickedItem

' Set default text for ComboBox to match the item that is clicked. Me.cbListViewCombo.Text = lvItem.Text

' Display the ComboBox, and make sure that it is on top with focus. Me.cbListViewCombo.Visible = True Me.cbListViewCombo.BringToFront Me.cbListViewCombo.Focus End If                   </li></ol>

Verify that it works

 * 1) Save and then run the sample.
 * 2) Click a row in the ListView control. Notice that a combo box appears over the location of the first column of the current row.
 * 3) To hide the combo box, click an item in the combo box, press ESC, and then scroll through the ListView control or click another control. Notice that the value that you clicked in the combo box is placed in the first column of the clicked row of the ListView control.

Keywords: kbvs2005swept kbvs2005applies kbhowtomaster KB320342

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.