datagrid绑定combobox控件

zm456 2005-01-13 04:45:33
datagrid每个网格中均显示为commobox控件,而且combobox永不hide...,技术上可行吗????

ps:不要那种当鼠标点击时才出现combobox控件的.
...全文
187 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
c11_11_11 2005-01-21
  • 打赏
  • 举报
回复
Protected Overloads Overrides Function GetPreferredHeight(ByVal g As Graphics, _

ByVal Value As Object) As Integer

Debug.WriteLine("GetPreferredHeight()")

Dim NewLineIndex As Integer = 0

Dim NewLines As Integer = 0

Dim ValueString As String = Me.GetText(Value)

Do

While NewLineIndex <> -1

NewLineIndex = ValueString.IndexOf("r\n", NewLineIndex + 1)

NewLines += 1

End While

Loop

Return FontHeight * NewLines + yMargin

End Function

Protected Overloads Overrides Function GetPreferredSize(ByVal g As Graphics, _

ByVal Value As Object) As Size

Dim Extents As Size = Size.Ceiling(g.MeasureString(GetText(Value), _

Me.DataGridTableStyle.DataGrid.Font))

Extents.Width += xMargin * 2 + DataGridTableGridLineWidth

Extents.Height += yMargin

Return Extents

End Function

Protected Overloads Overrides Sub Paint(ByVal g As Graphics, _

ByVal Bounds As Rectangle, _

ByVal Source As CurrencyManager, _

ByVal RowNum As Integer)

Paint(g, Bounds, Source, RowNum, False)

End Sub

Protected Overloads Overrides Sub Paint(ByVal g As Graphics, _

ByVal Bounds As Rectangle, _

ByVal Source As CurrencyManager, _

ByVal RowNum As Integer, _

ByVal AlignToRight As Boolean)

Dim Text As String = GetText(GetColumnValueAtRow(Source, RowNum))

PaintText(g, Bounds, Text, AlignToRight)

End Sub

Protected Overloads Sub Paint(ByVal g As Graphics, _

ByVal Bounds As Rectangle, _

ByVal Source As CurrencyManager, _

ByVal RowNum As Integer, _

ByVal BackBrush As Brush, _

ByVal ForeBrush As Brush, _

ByVal AlignToRight As Boolean)



Dim Text As String = GetText(GetColumnValueAtRow(Source, RowNum))

PaintText(g, Bounds, Text, BackBrush, ForeBrush, AlignToRight)

End Sub

Protected Overloads Overrides Sub SetDataGridInColumn(ByVal Value As DataGrid)

MyBase.SetDataGridInColumn(Value)

If Not (Combo.Parent Is Value) Then

If Not (Combo.Parent Is Nothing) Then

Combo.Parent.Controls.Remove(Combo)

End If

End If

If Not (Value Is Nothing) Then Value.Controls.Add(Combo)

End Sub

Protected Overloads Overrides Sub UpdateUI(ByVal Source As CurrencyManager, _

Val RowNum As Integer, ByVal InstantText As String)

Combo.Text = GetText(GetColumnValueAtRow(Source, RowNum))

If Not (InstantText Is Nothing) Then

Combo.Text = InstantText

End If

End Sub

c11_11_11 2005-01-21
  • 打赏
  • 举报
回复
Option Strict On

Option Explicit On

Imports System.Collections

Imports System.ComponentModel

Imports System.Drawing

Imports System.Windows.Forms

Imports System.Data



Public Class DataGridComboBox

‘与DataGridTextBox类相类似地定义一个在下拉框列类中使用的ComboBox

Inherits ComboBox

Public Sub New()

MyBase.New()

End Sub

Public isInEditOrNavigateMode As Boolean = True

End Class



Public Class DataGridComboBoxColumn

Inherits DataGridColumnStyle

' 与用户界面相关的变量

Private xMargin As Integer = 2

Private yMargin As Integer = 1

Private Combo As DataGridComboBox

Private _DisplayMember As String

Private _ValueMember As String

' 用于跟踪编辑状态变化的变量

Private OldVal As String = String.Empty

Private InEdit As Boolean = False

'构造函数 – 实例的DisplayMember, ValueMember值为由父类传来的integer类型的值

Public Sub New(ByRef DataSource As DataTable, _

ByVal DisplayMember As Integer, _

ByVal ValueMember As Integer)

Combo = New DataGridComboBox()

_DisplayMember = DataSource.Columns.Item(index:=DisplayMember).ToString

_ValueMember = DataSource.Columns.Item(index:=ValueMember).ToString

With Combo

.Visible = False

.DataSource = DataSource

.DisplayMember = _DisplayMember

.ValueMember = _ValueMember

End With

End Sub

'构造函数– 实例的DisplayMember, ValueMember 是String类型的值

Public Sub New(ByRef DataSource As DataTable, _

ByVal DisplayMember As String, _

ByVal ValueMember As String)

Combo = New DataGridComboBox()

With Combo

.Visible = False

.DataSource = DataSource

.DisplayMember = DisplayMember

.ValueMember = ValueMember

End With

End Sub

'------------------------------------------------------

'从 DataGridColumnStyle类继承下来的方法

'------------------------------------------------------

' 焦点离开combobox格后的改变

Protected Overloads Overrides Sub Abort(ByVal RowNum As Integer)

Debug.WriteLine("Abort()")

RollBack()

HideComboBox()

EndEdit()

End Sub

' 接受改变

Protected Overloads Overrides Function Commit(ByVal DataSource As CurrencyManager, _

ByVal RowNum As Integer) As Boolean

HideComboBox()

If Not InEdit Then

Return True

End If

Try

Dim Value As Object = Combo.SelectedValue

If NullText.Equals(Value) Then

Value = Convert.DBNull

End If

SetColumnValueAtRow(DataSource, RowNum, Value)

Catch e As Exception

RollBack()

Return False

End Try

EndEdit()

Return True

End Function

' 移开聚焦

Protected Overloads Overrides Sub ConcedeFocus()

Combo.Visible = False

End Sub

' 编辑单元格

Protected Overloads Overrides Sub Edit(ByVal Source As CurrencyManager, _

ByVal Rownum As Integer, _

ByVal Bounds As Rectangle, _

ByVal [ReadOnly] As Boolean, _

ByVal InstantText As String, _

ByVal CellIsVisible As Boolean)

Combo.Text = String.Empty

Dim OriginalBounds As Rectangle = Bounds

OldVal = Combo.Text

If CellIsVisible Then

Bounds.Offset(xMargin, yMargin)

Bounds.Width -= xMargin * 2

Bounds.Height -= yMargin

Combo.Bounds = Bounds

Combo.Visible = True

Else

Combo.Bounds = OriginalBounds

Combo.Visible = False

End If

Combo.SelectedValue = GetText(GetColumnValueAtRow(Source, Rownum))

If Not InstantText Is Nothing Then

Combo.SelectedValue = InstantText

End If

Combo.RightToLeft = Me.DataGridTableStyle.DataGrid.RightToLeft

Combo.Focus()

If InstantText Is Nothing Then

Combo.SelectAll()

Else

Dim [End] As Integer = Combo.Text.Length

Combo.Select([End], 0)

End If

If Combo.Visible Then

DataGridTableStyle.DataGrid.Invalidate(OriginalBounds)

End If

InEdit = True

End Sub

Protected Overloads Overrides Function GetMinimumHeight() As Integer

' 设置combobox的最小高度

Return Combo.PreferredHeight + yMargin

End Function

c11_11_11 2005-01-21
  • 打赏
  • 举报
回复
本节主要是和大家一起讨论一下怎样自建一个列类,并加入到Datagrid中进行使用。在上一节中和大家一起讨论了DataGridTextBoxColumn类,并在它基础上生成了一个继承自DataGridTextBoxColumn的具有改变cell与行(即一行内的cell的集合)变色能力的DataGridColoredTextBoxColumn类。要实现创建一个列类,应该很好地再次研究一下DataGridTextBoxColumn类,并据此相似的创建一个新类,本次示例是要创建一个具有下拉框的列(如图1所示),因此,它应该与DataGridTextBoxColumn类是同级的,也就是说它们应该是从同个父类派生出来的,这样才可以在保证在使用上的相似性与一致性。



图1 具有下拉框列的Datagrid

1. 何时会用到下拉框?

什么时候会用到下拉框列,一般来说,是当要在cell中填的内容是确知的几种可能之一时才会使用。那么数据源可能就会来自于两张数据表,一张是Datagrid整体体现的数据表,另一张是记录下拉框列表内容的。(当然,下拉框列表内容也可以不存放于数据库中,只是为了统一管理,笔者习惯于这么做)。在本例中,Datagrid的数据源为:



图2 Datagrid数据源

其中,“客户”表是Datagrid整体显示出来的内容的源表,由于“国家”列中所填的是确认的几个国家,因此笔者用“国家”表来记录在下拉框列表中显示出来的供用户选择的国家名。

2. 下拉框列的使用过程

现在来看一下下拉框列的使用过程:

图3 下拉框使用过程演示

从图3中,我们可以方便的了解到下拉框列的处理过程,在平常状况下,该列中的cell还是以textbox的形式进行显示的,下拉框的出现是被textbox中落入焦点才激发的,而后,该cell就是一个实实在在的下拉框了,当焦点离开该cell后,cell又恢复成一个textbox的模样了。

3. 类的制作

正式要开工了,先理一下思路,我们要做些什么事:

(1) 从DataGridTextBoxColumn类的父类DataGridColumnStyle继承一个自定义列类:DataGridComboBoxColumn;

(2) 在列中加入一个ComboBox实例,用于聚焦后的出现,与DataGridTextBoxColumn类使用的textbox所属的DataGridTextBox类相似的,我们应该设计一个专用的combobox类提供给DataGridComboBoxColumn类使用。

(3) 跟踪cell的状态,当聚焦时在textbox的外面添加一个combobox,失去焦点后隐藏起combobox,恢复成textbox;

(4) 重写父类的Edit与Paint方法,以适应Combobox的使用(关于Paint问题的具体讨论请见上一节)在Edit中将Combobox中产生的(用户输入或在下拉框中选择)变化记录入cell中,这也便于在更改后更新到相关的数据源中去,在本例中,笔者主要是示例实现下拉框与数据源的绑定功能,因此不支持用户输入,反而关注Combobox的DisplayMember与ValueMember属性,用于体现和数据源的关系。这点需要读者注意,如果您希望同时实现用户输入(这倒不是Combobox的优点了,对吧?)需要对笔者的代码进行适当的修改。

LiloZhu 2005-01-19
  • 打赏
  • 举报
回复
你可以Inherits DataGridColumnStyle 然後綁定 你所需的控件 進行重寫...
下面是我在我datagrid 中應用Checkbox,ComboBox,dateTimePicker 的例子,C#部分和我VB.net都有,希望對你有幫助....
VB.net 部分:
http://blog.csdn.net/zwxrain/archive/2005/01/19/258998.aspx

C#部分:
http://blog.csdn.net/zwxrain/archive/2005/01/19/259100.aspx
webserv2 2005-01-14
  • 打赏
  • 举报
回复
可以的
xiayule 2005-01-14
  • 打赏
  • 举报
回复
技术上是可行的
zm456 2005-01-14
  • 打赏
  • 举报
回复
To gzy11:用不用绑定都无所谓,只要能实现那种画面即可.

To xiayule , webserv2(GIS):可行的话,该怎么着写程序呢.思路就好,当然有代码更好.....

现在我是用DataGridTextBoxColumn().TextBox.Controls.Add(cmb)这种方式给一列加上cmb格式的,可这个样子当焦点离开网格的时候cmb就会不见,不是我们的初衷.重写DataGridColumnStyle吗???
蜗牛水里爬 2005-01-13
  • 打赏
  • 举报
回复
可以啊~事先先读取combobox的数据显示在你的datagrid控件中啊
绑定,局限性太大了,我一般都不用绑定的~
只不过这样做好象麻烦些,你说的我没试过能不能那样绑定。
我看看高手是如何回答的~

16,549

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧