来源Microsoft,文章 ID : 323167
创建示例
1. 按照如下步骤创建一个新的 Visual Basic Windows 应用程序项目:a. 启动 Microsoft Visual Studio .NET。
b. 在文件菜单上,指向新建,然后单击项目。
c. 在新建项目对话框中,单击对象类型下的 Visual Basic 项目,然后单击模板下的 Windows 应用程序。默认情况下将添加 Form1。
4. 将下面的代码添加到代码窗口的“Windows 窗体设计器生成代码”部分之后:Public MyCombo As New ComboBox()
Dim con As New SqlConnection("server=myservername;uid=myid;pwd=mypassword;database=northwind")
Dim daEmp As New SqlDataAdapter("Select * From Employees", con)
Public ds As New DataSet()
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddHandler MyCombo.TextChanged, AddressOf Ctrls_TextChanged
'Fill ComboBox list.
MyCombo.Name = "MyCombo"
MyCombo.Visible = False
MyCombo.Items.Clear()
MyCombo.Items.Add("Sales Representative")
MyCombo.Items.Add("Inside Sales Coordinator")
MyCombo.Items.Add("Vice President, Sales")
MyCombo.Items.Add("Sales Manager")
MyCombo.Items.Add("Flunky")
daEmp.Fill(ds, "Employees")
'Set the RowHeight of the DataGrid to the height of the ComboBox.
DataGrid1.PreferredRowHeight = MyCombo.Height
DataGrid1.DataSource = ds
DataGrid1.DataMember = "Employees"
'Add ComboBox to the Control collection of the DataGrid.
DataGrid1.Controls.Add(MyCombo)
End Sub
Private Sub DataGrid1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles DataGrid1.Paint
If DataGrid1.CurrentCell.ColumnNumber = 3 Then
MyCombo.Width = DataGrid1.GetCurrentCellBounds.Width
End If
End Sub
Private Sub Ctrls_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
If DataGrid1.CurrentCell.ColumnNumber = 3 Then
MyCombo.Visible = False
If DataGrid1.Item(DataGrid1.CurrentCell) & "" = "" Then
SendKeys.Send("*")
End If
DataGrid1.Item(DataGrid1.CurrentCell) = MyCombo.Text
End If
End Sub
Private Sub DataGrid1_CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGrid1.CurrentCellChanged
If DataGrid1.CurrentCell.ColumnNumber = 3 Then
MyCombo.Visible = False
MyCombo.Width = 0
MyCombo.Left = DataGrid1.GetCurrentCellBounds.Left
MyCombo.Top = DataGrid1.GetCurrentCellBounds.Top
MyCombo.Text = DataGrid1.Item(DataGrid1.CurrentCell) & ""
MyCombo.Visible = True
Else
MyCombo.Visible = False
MyCombo.Width = 0
End If
End Sub
Private Sub DataGrid1_Scroll(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGrid1.Scroll
MyCombo.Visible = False
MyCombo.Width = 0
End Sub
Private Sub DataGrid1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGrid1.Click
MyCombo.Visible = False
MyCombo.Width = 0
End Sub
一、将ComboBox绑定与DataGridColumnStyle ,然后对DataGridColumnStyle进行重写...
代码与下:
Imports System
Imports System.Drawing ‘一般在重绘时需要使用该命名空间
Imports System.Windows.Forms
Public Class X_DataGridComboBoxStyle
Inherits System.Windows.Forms.DataGridColumnStyle
'''定义一ComBox,然后将Combox 与DataGridColumnStyle绑定进行重写...
Private X_ComboBox As ComboBox = New ComboBox
Private IsEditing As Boolean
Sub New()
Me.X_ComboBox.Visible = False
End Sub
Protected Overrides Sub Abort(ByVal rowNum As Integer)
Me.IsEditing = False
Me.Invalidate()
End Sub
Protected Overrides Function Commit(ByVal dataSource As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer) As Boolean
Me.X_ComboBox.Bounds = Rectangle.Empty
AddHandler X_ComboBox.Click, AddressOf ComboBoxValueChanged '''激活事件
If Not Me.IsEditing Then
Return True
End If
IsEditing = False
Try
Dim value As String
value = X_ComboBox.Text
SetColumnValueAtRow(dataSource, rowNum, value)
Catch ex As Exception
Abort(rowNum)
Return False
End Try
invalidate()
Return True
End Function
Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
Dim value As String
value = Convert.ToString(GetColumnValueAtRow(source, rowNum))
If cellIsVisible Then
Me.X_ComboBox.Bounds = New Rectangle(bounds.X + 2, bounds.Y + 2, bounds.Width - 4, bounds.Height - 4)
Me.X_ComboBox.Text = value
Me.X_ComboBox.Visible = True
AddHandler X_ComboBox.Click, AddressOf ComboBoxValueChanged '''激活事件
Else
Me.X_ComboBox.Text = value
Me.X_ComboBox.Visible = False
End If
If Me.X_ComboBox.Visible Then
DataGridTableStyle.DataGrid.Invalidate(bounds)
End If
End Sub
Protected Overrides Function GetMinimumHeight() As Integer
Return 24
End Function
Protected Overrides Function GetPreferredHeight(ByVal g As System.Drawing.Graphics, ByVal value As Object) As Integer
Return 24
End Function
Protected Overrides Function GetPreferredSize(ByVal g As System.Drawing.Graphics, ByVal value As Object) As System.Drawing.Size
Return New Size(100, 24)
End Function
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer)
Paint(g, bounds, source, rowNum, False)
End Sub
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal alignToRight As Boolean)
Paint(g, bounds, source, rowNum, Brushes.Red, Brushes.Blue, alignToRight)
End Sub
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal foreBrush As Brush, ByVal backBrush As Brush, ByVal alignToRight As Boolean)
Dim dates As String = Convert.ToString(GetColumnValueAtRow(source, rowNum))
Dim rect As System.Drawing.Rectangle = bounds
g.FillRectangle(Brushes.White, rect)
rect.Offset(0, 2)
rect.Height -= 2
g.DrawString(dates, Me.DataGridTableStyle.DataGrid.Font, Brushes.Black, rect.X, rect.Y)
End Sub
Protected Overloads Overrides Sub SetDataGridInColumn(ByVal value As DataGrid)
MyBase.SetDataGridInColumn(value)
If Not Me.X_ComboBox.Parent Is Nothing Then
Me.X_ComboBox.Visible = False
Me.X_ComboBox.Controls.Remove(Me.X_ComboBox)
End If
If Not value Is Nothing Then
value.Controls.Add(Me.X_ComboBox)
End If
End Sub
'''定义一个ComboxChange 事件
Private Sub ComboBoxValueChanged(ByVal sender As Object, ByVal e As EventArgs)
Me.IsEditing = True
MyBase.ColumnStartedEditing(X_ComboBox)
End Sub
'''定义一个添加Combox的Items添加属性
Public Sub AddItem(ByVal StrItemName As String)
Me.X_ComboBox.Items.Add(StrItemName)
End Sub
End Class
思路:
1 写一个类comboForm表示下拉列表,类包含两个成员:Form窗体和DataGrid组件。
2 写一个类NoKeyUpComboBox(继承ComboBox),目的是屏蔽WM_KEYUP消息,避免在按Tab键时出现问题。
3 写一个继承于DataGridTextBoxColumn的类,命名为DataGridComboFormColumn。在类中加入一个ComboBox和一个comboForm,类实现下面几个功能:
a 编辑单元格内容时显示组件NoKeyUpComboBox;
b ComboBox下拉时显示下拉列表comboForm;
c 鼠标点击下拉列表时,隐藏comboForm并将用户选定的内容写入单元格(当然,你也可以设置其他隐藏下拉列表的操作,比如按回车键);
d 下拉列表comboForm不具有焦点时隐藏。
代码:
//comboForm类:
public class comboForm:Form
{
private DataGrid dataGrid;
public DataGrid DataGrid
{
get {return dataGrid;}
set {dataGrid=value;}
}
public comboForm()
{
this.FormBorderStyle=FormBorderStyle.None;
this.StartPosition=FormStartPosition.Manual;
dataGrid=new DataGrid();
this.Controls.Add(dataGrid);
dataGrid.Dock=DockStyle.Fill;
dataGrid.CaptionVisible=false;
}
}
//NoKeyUpComboBox类:
public class NoKeyUpComboBox:ComboBox
{
const int WM_KEYUP=0x101;
protected override void WndProc(ref Message msg)
{
if (msg.Msg==WM_KEYUP)
return;
base.WndProc(ref msg);
}
}
//DataGridComboFormColumn类:
public class DataGridComboFormColumn:DataGridTextBoxColumn
{
private NoKeyUpComboBox comboBox;
private CurrencyManager _source;
private int rowNum;
private comboForm frm;
public comboForm Frm
{
get {return frm;}
}
//我们将使用Index属性表示单元格内容与下拉列表的第Index列的内容相联系
private int index;
public int Index
{
get {return index;}
set {index=value;}
}