I createdsample application using DataGridView. Inside DGV i have one combo box column, i'll be binding this column only during run-time. I have also clearly specified the value for DataMember & DataValue propertyof combobox column. Andalso i set '8' for MaxDropDownItems property.After execution when i try to click the combobox, itsshowing only '8' items. I have an internal logic to show the recentselected item at the beggining,whenever item in combo gets selected.When this logic calls it will try to rebind the datasourceof combobox cell.Once all the things done, again when i click comboits not displaying only '8' items its displaying more than '8'.
Can any one help me?
Karthik - Changed TypeKarthikeyan Murthy Tuesday, August 11, 2009 3:52 PM
- Edited byKarthikeyan Murthy Friday, August 07, 2009 5:29 AM
-
| | Karthikeyan Murthy Thursday, August 06, 2009 3:23 PM | Hi Karthikeyan,
Based on my understanding, we need to handle the SelectedValueChanged event of the inner ComboBox to rebind the data source, not the CellClick event of the DataGridView. When user select a new value, we can reset the data source and save it to some members of the form. Then we rebind the inner ComboBox. When the cell ends editing, we need to refresh the data source we reset last time to the DataGridViewComboBoxColumn. This is my code snippet:
Public Class Form1
Private isCellClicked As Boolean
'These three members are used to save the rebound data source.
Private dataSource As Object
Private displayMember As String
Private valueMember As String
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Reset data source
ResetDataSource()
'Bind data source to column
RebindColUsers()
End Sub
Private Function LoadUsers() As DataTable
Dim dtUsers As New DataTable("Users")
Dim drUser As DataRow
dtUsers.Columns.Add(New DataColumn("user_id"))
dtUsers.Columns.Add(New DataColumn("user_name"))
For i As Integer = 1 To 25
drUser = dtUsers.NewRow()
drUser(0) = i
drUser(1) = "User " & i
dtUsers.Rows.Add(drUser)
Next
If isCellClicked Then
drUser = dtUsers.NewRow()
drUser(0) = -1
drUser(1) = "User -1"
dtUsers.Rows.InsertAt(drUser, 0)
End If
Return dtUsers
End Function
'Bind data source to ComboBox
Private Sub LoadUserComboBox(ByVal comboBox)
comboBox.DataSource = dataSource
comboBox.DisplayMember = displayMember
comboBox.ValueMember = valueMember
End Sub
'Bind data source to column
Private Sub RebindColUsers()
ColUsers.DataSource = dataSource
ColUsers.DisplayMember = displayMember
ColUsers.ValueMember = valueMember
End Sub
'Reset the data source
Private Sub ResetDataSource()
dataSource = LoadUsers()
displayMember = "user_name"
valueMember = "user_id"
End Sub
'Handle this event to handle the SelectedValueChanged event of the inner ComboBox
Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
If Me.DataGridView1.CurrentCell.ColumnIndex = 0 Then
'Get the inner ComboBox control.
Dim combo As ComboBox = TryCast(e.Control, ComboBox)
'Remove the old handler to avoid multiple handlers to be added
RemoveHandler combo.SelectedValueChanged, AddressOf Rebind
'Add the handler
AddHandler combo.SelectedValueChanged, AddressOf Rebind
End If
End Sub
'Rebind the ComboBox when user select a new value
Private Sub Rebind(ByVal obj As Object, ByVal args As EventArgs)
'Get the ComboBox
Dim combo As ComboBox = TryCast(obj, ComboBox)
'Backup the old selected value.
Dim val As Object = combo.SelectedValue
If Not (val Is Nothing) Then
'Remove the old handler to avoid refired SelectedValueChanged event.
RemoveHandler combo.SelectedValueChanged, AddressOf Rebind
'Rebind
isCellClicked = True
ResetDataSource()
LoadUserComboBox(combo)
isCellClicked = False
'Recover the selected value.
combo.SelectedValue = val
'Readd the handler.
AddHandler combo.SelectedValueChanged, AddressOf Rebind
End If
End Sub
Private Sub DataGridView1_CellEndEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
'Refresh the data source to column to keep consistence
RebindColUsers()
End Sub
End Class
Regards, Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. - Marked As Answer byAland LiMSFT, ModeratorThursday, August 20, 2009 2:54 AM
-
| | Aland Li Wednesday, August 19, 2009 12:00 PM | Hi Karthikeyan,
From my experience, we need to reset the MaxDropDownItems property of the DataGridViewComboBoxCell after we reset the data source of the DataGridViewComboBoxCell.
Let me know if this helps. Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. | | Aland Li Monday, August 10, 2009 7:03 AM | I tried this, even i'm getting the same issue. Any other way to handle this? Thanks,
Karthik | | Karthikeyan Murthy Tuesday, August 11, 2009 3:41 PM | Hi Karthikeyan,
Could you please post a code snippet? I have tested a similar project and did not met the error.
Best regards, Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. | | Aland Li Wednesday, August 12, 2009 2:49 AM |
Hi Aland,
Below is the sample code snippet. This will re-produce my scenario.
---------------------------------------------------------- Public
Class Form1
Private isCellClicked As Boolean
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
LoadUserComboBox()
End Sub
Private Function LoadUsers() As DataTable
Dim dtUsers As New DataTable("Users")
Dim drUser As DataRow
dtUsers.Columns.Add(
New DataColumn("user_id"))
dtUsers.Columns.Add(
New DataColumn("user_name"))
For i As Integer = 1 To 25
drUser = dtUsers.NewRow()
drUser(0) = i
drUser(1) =
"User " & i
dtUsers.Rows.Add(drUser)
Next
If isCellClicked Then
drUser = dtUsers.NewRow()
drUser(0) = -1
drUser(1) =
"User -1"
dtUsers.Rows.InsertAt(drUser, 0)
End If
Return dtUsers
End Function
Private Sub DataGridView1_CellClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellClick
' On click of Combo, i'm trying to re-bind datasource.
If e.ColumnIndex = 0 Then
isCellClicked =
True
LoadUserComboBox()
isCellClicked =
False
End If
End Sub
Private Sub LoadUserComboBox()
'"ColUsers" is the combox control inside the DataGridView
ColUsers.DataSource = LoadUsers()
ColUsers.DisplayMember =
"user_name"
ColUsers.ValueMember =
"user_id"
End Sub
End
Class --------------------------------------------------------------------------------
Thanks,
Karthik | | Karthikeyan Murthy Wednesday, August 12, 2009 10:59 AM | Please any one help meon the above issue
Thanks,
Karthik | | Karthikeyan Murthy Wednesday, August 19, 2009 9:14 AM | Hi Karthikeyan,
Based on my understanding, we need to handle the SelectedValueChanged event of the inner ComboBox to rebind the data source, not the CellClick event of the DataGridView. When user select a new value, we can reset the data source and save it to some members of the form. Then we rebind the inner ComboBox. When the cell ends editing, we need to refresh the data source we reset last time to the DataGridViewComboBoxColumn. This is my code snippet:
Public Class Form1
Private isCellClicked As Boolean
'These three members are used to save the rebound data source.
Private dataSource As Object
Private displayMember As String
Private valueMember As String
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Reset data source
ResetDataSource()
'Bind data source to column
RebindColUsers()
End Sub
Private Function LoadUsers() As DataTable
Dim dtUsers As New DataTable("Users")
Dim drUser As DataRow
dtUsers.Columns.Add(New DataColumn("user_id"))
dtUsers.Columns.Add(New DataColumn("user_name"))
For i As Integer = 1 To 25
drUser = dtUsers.NewRow()
drUser(0) = i
drUser(1) = "User " & i
dtUsers.Rows.Add(drUser)
Next
If isCellClicked Then
drUser = dtUsers.NewRow()
drUser(0) = -1
drUser(1) = "User -1"
dtUsers.Rows.InsertAt(drUser, 0)
End If
Return dtUsers
End Function
'Bind data source to ComboBox
Private Sub LoadUserComboBox(ByVal comboBox)
comboBox.DataSource = dataSource
comboBox.DisplayMember = displayMember
comboBox.ValueMember = valueMember
End Sub
'Bind data source to column
Private Sub RebindColUsers()
ColUsers.DataSource = dataSource
ColUsers.DisplayMember = displayMember
ColUsers.ValueMember = valueMember
End Sub
'Reset the data source
Private Sub ResetDataSource()
dataSource = LoadUsers()
displayMember = "user_name"
valueMember = "user_id"
End Sub
'Handle this event to handle the SelectedValueChanged event of the inner ComboBox
Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
If Me.DataGridView1.CurrentCell.ColumnIndex = 0 Then
'Get the inner ComboBox control.
Dim combo As ComboBox = TryCast(e.Control, ComboBox)
'Remove the old handler to avoid multiple handlers to be added
RemoveHandler combo.SelectedValueChanged, AddressOf Rebind
'Add the handler
AddHandler combo.SelectedValueChanged, AddressOf Rebind
End If
End Sub
'Rebind the ComboBox when user select a new value
Private Sub Rebind(ByVal obj As Object, ByVal args As EventArgs)
'Get the ComboBox
Dim combo As ComboBox = TryCast(obj, ComboBox)
'Backup the old selected value.
Dim val As Object = combo.SelectedValue
If Not (val Is Nothing) Then
'Remove the old handler to avoid refired SelectedValueChanged event.
RemoveHandler combo.SelectedValueChanged, AddressOf Rebind
'Rebind
isCellClicked = True
ResetDataSource()
LoadUserComboBox(combo)
isCellClicked = False
'Recover the selected value.
combo.SelectedValue = val
'Readd the handler.
AddHandler combo.SelectedValueChanged, AddressOf Rebind
End If
End Sub
Private Sub DataGridView1_CellEndEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
'Refresh the data source to column to keep consistence
RebindColUsers()
End Sub
End Class
Regards, Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. - Marked As Answer byAland LiMSFT, ModeratorThursday, August 20, 2009 2:54 AM
-
| | Aland Li Wednesday, August 19, 2009 12:00 PM | Thanks for you reply, Let me try this.
Thanks,
Karthik | | Karthikeyan Murthy Monday, August 24, 2009 3:10 PM | Hi Karthikeyan,
You are welcome. Ifmy solution does not work, please unmark it and tell me the problem.
Regards, Aland Li Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. | | Aland Li Tuesday, August 25, 2009 2:09 AM |
|