Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

4 days of hell

Status
Not open for further replies.

paulcarey

Programmer
Jun 15, 2001
45
GB
I have spent 4 days, yes 4!, searching , reading and not understanding a word about getting a combo box in a datagrid.

I have a class I call it, nothing happens, no errors, just me screaming!

If I show my code could someone tell me whats wrong? Theres a mars bar in it!

'This is the form it's called from
[vbcode]
Private Sub LoadRotaGrid()

Me.SuspendLayout()

'load rotaGrid
Dim oRota As StaffRota = New StaffRota
Dim oDataRota As DataTable = oRota.GetRotaData '\\CoreData
Dim oDataStaff As DataTable = oRota.GetSSStaff '\\ComboData

Dim oTblStyle As New DataGridTableStyle
oTblStyle.MappingName() = "Rota"

'ComboBox Column
Dim aCol3 As New DataGridComboBoxColumn
With aCol3
.MappingName = "RotaEmployee" '\\coredata field to match
.HeaderText = "Employee"
.Width = 100
.ColumnComboBox.DataSource = oDataStaff
.ColumnComboBox.DisplayMember = "FullName"
.ColumnComboBox.ValueMember = "EmployeeID" '//combodata field to match
oTblStyle.PreferredRowHeight = .ColumnComboBox.Height
oTblStyle.GridColumnStyles.Add(aCol3)
End With

With grdRota
.TableStyles.Clear()
.TableStyles.Add(oTblStyle)
.DataSource = oDataRota
End With

Me.ResumeLayout()

End Sub

[/vbcode]

'Here's the class
[vbcode]
Imports System

'
' Derive a custom column style from DataGridTextBoxColumn that:
' - adds a ComboBox member
' - tracks when the combobox has focus in the Enter and Leave events
' - overrides Edit event so the ComboBox replaces the TextBox
' - overrides Commit event to save the changed data
'

Public Class DataGridComboBoxColumn

#Region " Declarations "

Inherits DataGridTextBoxColumn

Public ColumnComboBox As NoKeyUpCombo

Private mcmSource As System.Windows.Forms.CurrencyManager
Private mintRowNum As Integer
Private mblnEditing As Boolean

#End Region

#Region " Constructor "

Public Sub New()

mcmSource = Nothing
mblnEditing = False

ColumnComboBox = New NoKeyUpCombo
ColumnComboBox.DropDownStyle = ComboBoxStyle.DropDownList

AddHandler ColumnComboBox.Leave, AddressOf LeaveComboBox
AddHandler ColumnComboBox.SelectionChangeCommitted, AddressOf ComboStartEditing

End Sub

#End Region

#Region " Private Methods "

Private Sub HandleScroll(ByVal sender As Object, ByVal e As EventArgs)

If ColumnComboBox.Visible Then ColumnComboBox.Hide()

End Sub

Private Sub ComboStartEditing(ByVal sender As Object, ByVal e As EventArgs)

mblnEditing = True
MyBase.ColumnStartedEditing(DirectCast(sender, System.Windows.Forms.Control))

End Sub

Private Sub LeaveComboBox(ByVal sender As Object, ByVal e As EventArgs)

If mblnEditing Then
SetColumnValueAtRow(mcmSource, mintRowNum, ColumnComboBox.Text)
mblnEditing = False
Invalidate()
End If

ColumnComboBox.Hide()
AddHandler Me.DataGridTableStyle.DataGrid.Scroll, New EventHandler(AddressOf HandleScroll)

End Sub

#End Region

#Region " Overridden Methods "

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)

MyBase.Edit([source], rowNum, bounds, [readOnly], instantText, cellIsVisible)

mintRowNum = rowNum
mcmSource = [source]

With ColumnComboBox
.Parent = Me.TextBox.Parent
.Location = Me.TextBox.Location
.Size = New Size(Me.TextBox.Size.Width, .Size.Height)
.SelectedIndex = .FindStringExact(Me.TextBox.Text)
.Text = Me.TextBox.Text

Me.TextBox.Visible = False
.Visible = True

AddHandler Me.DataGridTableStyle.DataGrid.Scroll, AddressOf HandleScroll

.BringToFront()
.Focus()
End With

End Sub

Protected Overrides Function Commit( _
ByVal dataSource As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer) As Boolean

If mblnEditing Then
mblnEditing = False
SetColumnValueAtRow(dataSource, rowNum, ColumnComboBox.Text)
End If

Return True

End Function

Protected Overrides Sub ConcedeFocus()

Console.WriteLine("ConcedeFocus")
MyBase.ConcedeFocus()

End Sub

Protected Overrides Function GetColumnValueAtRow( _
ByVal [source] As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer) As Object

Dim s As Object = MyBase.GetColumnValueAtRow([source], rowNum)
Dim dv As DataView = CType(Me.ColumnComboBox.DataSource, DataView)
Dim rowCount As Integer = dv.Count
Dim i As Integer = 0
Dim obj As Object

While i < rowCount
obj = dv(i)(Me.ColumnComboBox.ValueMember)
If (Not obj Is DBNull.Value) AndAlso _
(Not s Is DBNull.Value) AndAlso _
(s Is obj) Then

Exit While
End If

i += 1
End While

If i < rowCount Then
Return dv(i)(Me.ColumnComboBox.DisplayMember)
End If

Return DBNull.Value

End Function

Protected Overrides Sub SetColumnValueAtRow( _
ByVal [source] As System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer, ByVal value As Object)

Dim s As Object = value
Dim dv As DataView = CType(Me.ColumnComboBox.DataSource, DataView)
Dim rowCount As Integer = dv.Count
Dim i As Integer = 0
Dim obj As Object

While i < rowCount
obj = dv(i)(Me.ColumnComboBox.DisplayMember)

If (Not obj Is DBNull.Value) AndAlso _
(s Is obj) Then

Exit While
End If

i += 1
End While

If i < rowCount Then
s = dv(i)(Me.ColumnComboBox.ValueMember)
Else
s = DBNull.Value
End If

MyBase.SetColumnValueAtRow([source], rowNum, s)
End Sub

#End Region

Private Sub InitializeComponent()

End Sub

End Class
[/vbcode]
A related class
[vbcode]
Public Class NoKeyUpCombo
Inherits System.Windows.Forms.ComboBox

Private Const WM_KEYUP As Integer = &H101

Protected Overrides Sub WndProc(ByRef theMessage As System.Windows.Forms.Message)
'
' Ignore KeyUp event to avoid problem with tabbing the dropdown.
' Prevent tabbing through cells from leaving focus over the cell
' that contains the combobox.
'
If theMessage.Msg = WM_KEYUP Then
Return
Else
MyBase.WndProc(theMessage)
End If

End Sub
End Class
[/vbcode]
 
I would have expected that the DataGridComboColumn would derive from DataGridColumnStyle rather than DataGridTextBoxColumn along with a DataGridComboBox derived from ComboBox.

This would tie in with the way the DataGridTextBoxColumn and the DataGridTextBox are defined.

Alternatively buy the Janus GridEX component that has full support for combo boxes and calendar combo boxes built in.

It probably costs less than 4 days of your time.



Bob Boffin
 
4*8*$6.25 = $200 (minimum wage)
4*8*$40.00 = $1280 (low end consultant bill rate, not pay rate)
4*8*$200.00 = $6400 (high end consultant)

Component One Flexgrid = $299 (renewal) $499 (full), free trials available

There are many other options available too, I'm just a fan of the C1 tools and their excellent support. That $499 is a subscription, not just the product. So depending on how much it costs your employer to have you sit in your seat, it may be well worth it to to drop the money on a tool to make your job easier.

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
paul,

I had the same task of adding a combobox to a datagrid, and spent 6 days trying to figure it out.(just joking)

I looked at your code, and I'm not sure what me.resumelayout does but I think all you need to do is add a few more lines of code:

'your code
With grdRota
.TableStyles.Clear()
.TableStyles.Add(oTblStyle)
.DataSource = oDataRota
End With

'add this code after your code
Dim dgtb As DataGridTextBoxColumn
dgtb = CType(Datagrid2.TableStyles(0).GridColumnStyles(2), DataGridTextBoxColumn)

dgtb.TextBox.Controls.Add(aCol3)
'------

But, anyway I will post some of my code, that may assist you with your problem if that was not the solution.

In the form load event I put the code to create a combo box and the add handler code. You can put this in a different routine I just wanted to create the control as soon as the form loaded.

code:
'create a combo box for datagrid2
'set combo box settings
cboBox = New ComboBox
cboBox.Cursor = System.Windows.Forms.Cursors.Arrow
cboBox.DropDownStyle = ComboBoxStyle.DropDownList
cboBox.BackColor = Color.LightPink
cboBox.Dock = DockStyle.Fill
cboBox.Items.Add("VarChar")
cboBox.Items.Add("Int")
cboBox.Items.Add("char")
cboBox.SelectedIndex = 0

'add event handler for combo box
AddHandler cboBox.SelectedIndexChanged, AddressOf cboBox_SelectedIndexChanged


Then in my populate datagrid control subroutine I did a few things.

1) created a datagrid style
2) created datagrid column style

and then "after" I binded the table to the data grid I have the following code:

Dim dgtb As DataGridTextBoxColumn
dgtb = CType(Datagrid2.TableStyles(0).GridColumnStyles(2), DataGridTextBoxColumn)

dgtb.TextBox.Controls.Add(cboBox)

 
Thanks very much for your help. I'll have a look a bit later when I've recovered the will to live!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top