• 全部
  • VBS
  • .NET技术
  • VBA
  • VB网络编程
  • VB多媒体
  • VB数据库
  • VB控件
  • VB COM/DCOM
  • VB基础类
  • VB API
  • 问答

如何在datagrid单元格里加个列表框?

jsfeiyu 2005-02-21 11:32:45
大家帮忙!!!
...全文
86 点赞 收藏 6
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
T2 2005-02-21
来源Microsoft,文章 ID : 323167
创建示例
1. 按照如下步骤创建一个新的 Visual Basic Windows 应用程序项目:a. 启动 Microsoft Visual Studio .NET。
b. 在文件菜单上,指向新建,然后单击项目。
c. 在新建项目对话框中,单击对象类型下的 Visual Basic 项目,然后单击模板下的 Windows 应用程序。默认情况下将添加 Form1。

2. 将一个 DataGrid 控件从工具箱到拖到 Form1。
3. 将下面的代码添加到代码窗口顶部的 Form1.vb 的“声明”部分中:Imports System.Data.SqlClient
Imports System.Windows.Forms


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


5. 根据您的环境需要修改连接字符串。
6. 按 F5 键运行该项目。单击 DataGrid 中“标题”列中的一个字段。您会注意到 ComboBox 控件位于 DataGrid 中。
7. 展开 ComboBox。您会注意到显示出了一个标题列表。
回复
Night_Elf 2005-02-21
来源:99SOFT.NET,瞬间粘贴的,呵呵!
回复
hamadou 2005-02-21
一、将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

回复
menuvb 2005-02-21
楼上暴强,哈哈
回复
Night_Elf 2005-02-21
//点击下拉列表的DataGrid时,将选中的内容写入单元格并隐藏下拉列表--Frm
private void grid_click(object sender,EventArgs e)
{
BindingManagerBase cm=frm.BindingContext[Frm.DataGrid.DataSource, frm.DataGrid.DataMember];
comboBox.Text=((DataRowView)cm.Current)[index].ToString();
this.TextBox.Text=((DataRowView)cm.Current)[index].ToString();
frm.Hide();
comboBox.Visible=false;
this.SetColumnValueAtRow(_source,rowNum,this.TextBox.Text);
}
//重载Edit方法,使用comboBox代替TextBox
protected override void Edit(CurrencyManager dataSource,int rowNum,Rectangle bounds,bool readOnly,string instanttext,bool cellVisible)
{
base.Edit(dataSource,rowNum,bounds,readOnly,instanttext,cellVisible);
comboBox.Parent=this.TextBox.Parent;
comboBox.Left=this.TextBox.Left-2;
comboBox.Top=this.TextBox.Top-2;
comboBox.Size=new Size(this.TextBox.Width,this.comboBox.Height);
comboBox.Text=this.TextBox.Text;

this.TextBox.Visible=false;
comboBox.Visible=true;
comboBox.BringToFront();
comboBox.Focus();
_source=dataSource;
this.rowNum=rowNum;
}
}


下面的例子说明了如何使用DataGridComboFrom类:
新建一个Windows 应用程序,加入SqlConnection,连接SQL数据库Northwind,加入下面代码。

private void Form1_Load(object sender, System.EventArgs e)
{
SqlDataAdapter da=new SqlDataAdapter("select ProductName from Products",this.sqlConnection1);
DataSet ds=new DataSet();
da.Fill(ds,"products");
DataSet ds_Combo=new DataSet();
da.SelectCommand=new SqlCommand("select ProductName,QuantityPerUnit,UnitPrice from Products",this.sqlConnection1);
da.Fill(ds_Combo,"products");

DataGridTableStyle dts=new DataGridTableStyle();
dts.MappingName="products";
myDataGridColumn col=new myDataGridColumn();
col.MappingName="ProductName";
col.Width=100;
col.Index=0;
col.HeaderText="ProductName";

col.Frm.DataGrid.DataSource=ds_Combo;//设置下拉列表的数据源
col.Frm.DataGrid.DataMember="products";
dts.GridColumnStyles.Add(col);

this.dataGrid1.TableStyles.Add(dts);
this.dataGrid1.SetDataBinding(ds,"products");
}

回复
Night_Elf 2005-02-21
思路:
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;}
}

public DataGridComboFormColumn()
{
frm=new comboForm();
comboBox=new NoKeyUpComboBox();
frm.Deactivate+=new EventHandler(frm_deactive);
frm.DataGrid.Click+=new EventHandler(grid_click);
this.comboBox.DropDown+=new EventHandler(comboBox_dropDown);
this.comboBox.Leave+=new EventHandler(comboBox_leave);
}
//comboBox不具有焦点时隐藏
private void comboBox_leave(object sender,EventArgs e)
{
comboBox.Visible=false;
}
//下拉列表--Frm不具有焦点时隐藏
private void frm_deactive(object sender,EventArgs e)
{
frm.Hide();
comboBox.Visible=false;
}
//comboBox下拉时显示下拉列表--Frm
private void comboBox_dropDown(object sender,EventArgs e)
{
//在这里您还可以根据下拉列表的长与宽是否超出屏幕设置下拉列表的位置
frm.Left=comboBox.PointToScreen(new Point(0,comboBox.Height)).X;
frm.Top=comboBox.PointToScreen(new Point(0,comboBox.Height)).Y;
frm.Show();
frm.BringToFront();
}

回复
相关推荐
发帖
VB
创建于2007-09-28

1.6w+

社区成员

VB技术相关讨论,主要为经典vb,即VB6.0
申请成为版主
帖子事件
创建了帖子
2005-02-21 11:32
社区公告
暂无公告