Solved

Databinding not working with combox vb.net

Posted on 2015-01-29
1
135 Views
Last Modified: 2015-02-02
Hi all.

I'm working on some vb.net code that is not working as I'd like. I have form1 that has a datagrid. When the end user right clicks a record in the datagrid and selects "View Details" then it opens form2 with record information. One of those fields is a combo box. When form2 opens I want it to display the selected value to equal whatever "MinQtyValue" is. Unfortunately, when form2 opens it does not show a selection. Below is my code, I also added a databinding to a textbox to make sure there was data and yes, when form2 opens the textbox shows "MinQtyValue" but the combobox does not:

sda.Fill(ds, "MinQtyValue")
            bs = New BindingSource(ds, "MinQtyValue")
            DataBindings.Clear()
            frm.txtMinQtyValue.DataBindings.Add("Text", bs, "MinQtyValue")

            sda.Fill(ds, "MinQtyValue")
            bs = New BindingSource(ds, "MinQtyValue")
            DataBindings.Clear()
            frm.cmbSetMin.DataBindings.Add("SelectedValue", bs, "MinQtyValue")

Open in new window


Thank you in advance!
0
Comment
Question by:printmedia
1 Comment
 
LVL 32

Accepted Solution

by:
it_saige earned 500 total points
ID: 40580850
In order to use a combobox binding to SelectedValue, the Value *must* be a type of the object that is databound.

A quick and dirty example -

MainForm.vb -
Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Public Class MainForm
	Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
		Globals.Technicians = New BindingList(Of Person) From _
		 { _
		   New Person() With {.ID = 1, .Name = "--- Unassigned ---"}, _
		   New Person() With {.ID = 2, .Name = "Peter"}, _
		   New Person() With {.ID = 3, .Name = "Paul"}, _
		   New Person() With {.ID = 4, .Name = "Mary"} _
		 }

		Globals.Tasks = New BindingList(Of Task) From _
		 { _
		  New Task() With {.ID = 1, .Name = "Sweep", .AssignedTo = Globals.Technicians(0)}, _
		  New Task() With {.ID = 2, .Name = "Mop", .AssignedTo = Globals.Technicians(0)}, _
		  New Task() With {.ID = 3, .Name = "Wash", .AssignedTo = Globals.Technicians(0)}, _
		  New Task() With {.ID = 4, .Name = "Dry", .AssignedTo = Globals.Technicians(0)} _
		 }

		taskSource.DataSource = Globals.Tasks
		TaskGrid.DataSource = taskSource
	End Sub

	Private Sub OnCellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) Handles TaskGrid.CellFormatting
		If TypeOf sender Is DataGridView Then
			Dim dgv As DataGridView = DirectCast(sender, DataGridView)
			If dgv.Columns(e.ColumnIndex).Name.Equals(colAssignedOn.Name) Or dgv.Columns(e.ColumnIndex).Name.Equals(colCompletedOn.Name) Then
				Dim [date] As DateTime
				e.Value = If(DateTime.TryParse(e.Value.ToString(), [date]), If([date] <> DateTime.MinValue, [date].ToShortDateString(), "Not Set"), "Not Set")
				e.FormattingApplied = True
			ElseIf dgv.Columns(e.ColumnIndex).Name.Equals(colStatus.Name) Then
				Dim status As Status
				If TypeOf e.Value Is Status Then status = DirectCast(e.Value, Status)
				e.Value = status.GetEnumDescription()
				e.FormattingApplied = True
			End If
		End If
	End Sub

	Private Sub OnRowContextMenuStripNeeded(ByVal sender As Object, ByVal e As DataGridViewRowContextMenuStripNeededEventArgs) Handles TaskGrid.RowContextMenuStripNeeded
		If TypeOf sender Is DataGridView Then
			Dim dgv As DataGridView = DirectCast(sender, DataGridView)
			If Not dgv.SelectedRows.Contains(dgv.Rows(e.RowIndex)) Then dgv.Rows(e.RowIndex).Selected = True
			e.ContextMenuStrip = GridContextMenu
		End If
	End Sub

	Private Sub OnClick(ByVal sender As Object, ByVal e As EventArgs) Handles ViewDetailToolStripMenuItem.Click
		Dim task As Task = Nothing
		Dim editor As DetailsView = Nothing
		If TaskGrid.SelectedRows.Count = 1 Then
			task = DirectCast(TaskGrid.SelectedRows(0).DataBoundItem, Task)
			editor = New DetailsView(task)
			editor.ShowDialog()
		End If
	End Sub
End Class

Module Globals
	Public Property Technicians() As BindingList(Of Person) = New BindingList(Of Person)
	Public Property Tasks() As BindingList(Of Task) = New BindingList(Of Task)
End Module

Module Extensions
	<Extension()> _
	Public Function GetEnumDescription(ByVal Value As [Enum]) As String
		Dim _fieldInfo = Value.GetType().GetField(Value.ToString())
		Dim attributes = _fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False)
		Return If(attributes.Length > 0, attributes(0).Description, Value.ToString())
	End Function
End Module

Public Class Task
	Public Property ID() As Integer
	Public Property Name() As String
	Public Property AssignedTo() As Person
	Public Property AssignedOn() As DateTime
	Public Property CompletedOn() As DateTime
	Public Property Status() As Status
End Class

Public Enum Status
	<Description("None")> None = 0
	<Description("Unassigned")> Unassigned
	<Description("Assigned")> Assigned
	<Description("In Progress")> InProgress
	<Description("In Research")> InResearch
	<Description("Completed")> Completed
End Enum

Public Class Person
	Public Property ID() As Integer
	Public Property Name() As String

	Public Overrides Function ToString() As String
		Return Name
	End Function
End Class

Open in new window

MainForm.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class MainForm
	Inherits System.Windows.Forms.Form

	'Form overrides dispose to clean up the component list.
	<System.Diagnostics.DebuggerNonUserCode()> _
	Protected Overrides Sub Dispose(ByVal disposing As Boolean)
		Try
			If disposing AndAlso components IsNot Nothing Then
				components.Dispose()
			End If
		Finally
			MyBase.Dispose(disposing)
		End Try
	End Sub

	'Required by the Windows Form Designer
	Private components As System.ComponentModel.IContainer

	'NOTE: The following procedure is required by the Windows Form Designer
	'It can be modified using the Windows Form Designer.  
	'Do not modify it using the code editor.
	<System.Diagnostics.DebuggerStepThrough()> _
	Private Sub InitializeComponent()
		Me.components = New System.ComponentModel.Container()
		Me.TaskGrid = New System.Windows.Forms.DataGridView()
		Me.colID = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colName = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colAssignedTo = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colAssignedOn = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colCompletedOn = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colStatus = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.taskSource = New System.Windows.Forms.BindingSource(Me.components)
		Me.GridContextMenu = New System.Windows.Forms.ContextMenuStrip(Me.components)
		Me.ViewDetailToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
		CType(Me.TaskGrid, System.ComponentModel.ISupportInitialize).BeginInit()
		CType(Me.taskSource, System.ComponentModel.ISupportInitialize).BeginInit()
		Me.GridContextMenu.SuspendLayout()
		Me.SuspendLayout()
		'
		'TaskGrid
		'
		Me.TaskGrid.AllowUserToAddRows = False
		Me.TaskGrid.AllowUserToDeleteRows = False
		Me.TaskGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
		Me.TaskGrid.Columns.AddRange(New System.Windows.Forms.DataGridViewColumn() {Me.colID, Me.colName, Me.colAssignedTo, Me.colAssignedOn, Me.colCompletedOn, Me.colStatus})
		Me.TaskGrid.Location = New System.Drawing.Point(13, 13)
		Me.TaskGrid.MultiSelect = False
		Me.TaskGrid.Name = "TaskGrid"
		Me.TaskGrid.ReadOnly = True
		Me.TaskGrid.RowHeadersVisible = False
		Me.TaskGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect
		Me.TaskGrid.Size = New System.Drawing.Size(503, 237)
		Me.TaskGrid.TabIndex = 0
		'
		'colID
		'
		Me.colID.DataPropertyName = "ID"
		Me.colID.HeaderText = "ID"
		Me.colID.Name = "colID"
		Me.colID.ReadOnly = True
		Me.colID.Visible = False
		'
		'colName
		'
		Me.colName.DataPropertyName = "Name"
		Me.colName.HeaderText = "Task Name"
		Me.colName.Name = "colName"
		Me.colName.ReadOnly = True
		'
		'colAssignedTo
		'
		Me.colAssignedTo.DataPropertyName = "AssignedTo"
		Me.colAssignedTo.HeaderText = "Assigned To"
		Me.colAssignedTo.Name = "colAssignedTo"
		Me.colAssignedTo.ReadOnly = True
		'
		'colAssignedOn
		'
		Me.colAssignedOn.DataPropertyName = "AssignedOn"
		Me.colAssignedOn.HeaderText = "Assigned On"
		Me.colAssignedOn.Name = "colAssignedOn"
		Me.colAssignedOn.ReadOnly = True
		'
		'colCompletedOn
		'
		Me.colCompletedOn.DataPropertyName = "CompletedOn"
		Me.colCompletedOn.HeaderText = "Completed On"
		Me.colCompletedOn.Name = "colCompletedOn"
		Me.colCompletedOn.ReadOnly = True
		'
		'colStatus
		'
		Me.colStatus.DataPropertyName = "Status"
		Me.colStatus.HeaderText = "Current Status"
		Me.colStatus.Name = "colStatus"
		Me.colStatus.ReadOnly = True
		'
		'GridContextMenu
		'
		Me.GridContextMenu.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ViewDetailToolStripMenuItem})
		Me.GridContextMenu.Name = "GridContextMenu"
		Me.GridContextMenu.Size = New System.Drawing.Size(133, 26)
		'
		'ViewDetailToolStripMenuItem
		'
		Me.ViewDetailToolStripMenuItem.Name = "ViewDetailToolStripMenuItem"
		Me.ViewDetailToolStripMenuItem.Size = New System.Drawing.Size(132, 22)
		Me.ViewDetailToolStripMenuItem.Text = "View Detail"
		'
		'MainForm
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(532, 262)
		Me.Controls.Add(Me.TaskGrid)
		Me.Name = "MainForm"
		Me.Text = "Form1"
		CType(Me.TaskGrid, System.ComponentModel.ISupportInitialize).EndInit()
		CType(Me.taskSource, System.ComponentModel.ISupportInitialize).EndInit()
		Me.GridContextMenu.ResumeLayout(False)
		Me.ResumeLayout(False)

	End Sub
	Friend WithEvents TaskGrid As System.Windows.Forms.DataGridView
	Friend WithEvents taskSource As System.Windows.Forms.BindingSource
	Friend WithEvents colID As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colName As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colAssignedTo As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colAssignedOn As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colCompletedOn As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colStatus As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents GridContextMenu As System.Windows.Forms.ContextMenuStrip
	Friend WithEvents ViewDetailToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem

End Class

Open in new window

DetailsView.vb -
Public Class DetailsView
	Private fTask As Task
	Private techSource As List(Of Person)

	Public ReadOnly Property Task() As Task
		Get
			Return fTask
		End Get
	End Property

	Private Sub New()
		Me.New(New Task())
	End Sub

	Public Sub New(ByRef Task As Task)
		InitializeComponent()
		fTask = If(Task Is Nothing, New Task(), Task)

		cmbStatus.DataSource = (From value As [Enum] In [Enum].GetValues(GetType(Status)).Cast(Of Status)() Select New With {.Display = value.GetEnumDescription(), .Value = value}).ToList()
		cmbStatus.DisplayMember = "Display"
		cmbStatus.ValueMember = "Value"

		cmbTechnicians.DataSource = (From value As Person In Globals.Technicians Select New With {.Display = value.ToString(), .Value = value}).ToList()
		cmbTechnicians.DisplayMember = "Display"
		cmbTechnicians.ValueMember = "Value"

		dtpAssignedOn.DataBindings.Add(New Binding("Text", fTask, "AssignedOn", True, DataSourceUpdateMode.OnPropertyChanged))
		dtpCompletedOn.DataBindings.Add(New Binding("Text", fTask, "CompletedOn", True, DataSourceUpdateMode.OnPropertyChanged))
		tbID.DataBindings.Add(New Binding("Text", fTask, "ID", True, DataSourceUpdateMode.OnPropertyChanged))
		tbName.DataBindings.Add(New Binding("Text", fTask, "Name", True, DataSourceUpdateMode.OnPropertyChanged))
		cmbTechnicians.DataBindings.Add(New Binding("SelectedValue", fTask, "AssignedTo", True, DataSourceUpdateMode.OnPropertyChanged))
		cmbStatus.DataBindings.Add(New Binding("SelectedValue", fTask, "Status", True, DataSourceUpdateMode.OnPropertyChanged))
	End Sub
End Class

Open in new window

DetailsView.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class DetailsView
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Dim lblAssignedOn As System.Windows.Forms.Label
		Dim lblCompletedOn As System.Windows.Forms.Label
		Dim lblName As System.Windows.Forms.Label
		Dim lblStatus As System.Windows.Forms.Label
		Dim Label1 As System.Windows.Forms.Label
		Dim lblID As System.Windows.Forms.Label
		Me.dtpAssignedOn = New System.Windows.Forms.DateTimePicker()
		Me.dtpCompletedOn = New System.Windows.Forms.DateTimePicker()
		Me.tbName = New System.Windows.Forms.TextBox()
		Me.cmbStatus = New System.Windows.Forms.ComboBox()
		Me.cmbTechnicians = New System.Windows.Forms.ComboBox()
		Me.tbID = New System.Windows.Forms.TextBox()
		lblAssignedOn = New System.Windows.Forms.Label()
		lblCompletedOn = New System.Windows.Forms.Label()
		lblName = New System.Windows.Forms.Label()
		lblStatus = New System.Windows.Forms.Label()
		Label1 = New System.Windows.Forms.Label()
		lblID = New System.Windows.Forms.Label()
		Me.SuspendLayout()
		'
		'lblAssignedOn
		'
		lblAssignedOn.AutoSize = True
		lblAssignedOn.Location = New System.Drawing.Point(12, 95)
		lblAssignedOn.Name = "lblAssignedOn"
		lblAssignedOn.Size = New System.Drawing.Size(70, 13)
		lblAssignedOn.TabIndex = 1
		lblAssignedOn.Text = "Assigned On:"
		'
		'lblCompletedOn
		'
		lblCompletedOn.AutoSize = True
		lblCompletedOn.Location = New System.Drawing.Point(12, 121)
		lblCompletedOn.Name = "lblCompletedOn"
		lblCompletedOn.Size = New System.Drawing.Size(77, 13)
		lblCompletedOn.TabIndex = 3
		lblCompletedOn.Text = "Completed On:"
		'
		'lblName
		'
		lblName.AutoSize = True
		lblName.Location = New System.Drawing.Point(12, 41)
		lblName.Name = "lblName"
		lblName.Size = New System.Drawing.Size(65, 13)
		lblName.TabIndex = 7
		lblName.Text = "Task Name:"
		'
		'lblStatus
		'
		lblStatus.AutoSize = True
		lblStatus.Location = New System.Drawing.Point(12, 147)
		lblStatus.Name = "lblStatus"
		lblStatus.Size = New System.Drawing.Size(40, 13)
		lblStatus.TabIndex = 9
		lblStatus.Text = "Status:"
		'
		'Label1
		'
		Label1.AutoSize = True
		Label1.Location = New System.Drawing.Point(12, 68)
		Label1.Name = "Label1"
		Label1.Size = New System.Drawing.Size(69, 13)
		Label1.TabIndex = 12
		Label1.Text = "Assigned To:"
		'
		'lblID
		'
		lblID.AutoSize = True
		lblID.Location = New System.Drawing.Point(12, 15)
		lblID.Name = "lblID"
		lblID.Size = New System.Drawing.Size(21, 13)
		lblID.TabIndex = 5
		lblID.Text = "ID:"
		'
		'dtpAssignedOn
		'
		Me.dtpAssignedOn.CustomFormat = "MM/dd/yyyy"
		Me.dtpAssignedOn.Location = New System.Drawing.Point(95, 92)
		Me.dtpAssignedOn.Name = "dtpAssignedOn"
		Me.dtpAssignedOn.Size = New System.Drawing.Size(121, 20)
		Me.dtpAssignedOn.TabIndex = 2
		'
		'dtpCompletedOn
		'
		Me.dtpCompletedOn.CustomFormat = "MM/dd/yyyy"
		Me.dtpCompletedOn.Location = New System.Drawing.Point(95, 118)
		Me.dtpCompletedOn.Name = "dtpCompletedOn"
		Me.dtpCompletedOn.Size = New System.Drawing.Size(121, 20)
		Me.dtpCompletedOn.TabIndex = 4
		'
		'tbName
		'
		Me.tbName.Location = New System.Drawing.Point(95, 38)
		Me.tbName.Name = "tbName"
		Me.tbName.Size = New System.Drawing.Size(121, 20)
		Me.tbName.TabIndex = 8
		'
		'cmbStatus
		'
		Me.cmbStatus.FormattingEnabled = True
		Me.cmbStatus.Location = New System.Drawing.Point(95, 144)
		Me.cmbStatus.Name = "cmbStatus"
		Me.cmbStatus.Size = New System.Drawing.Size(121, 21)
		Me.cmbStatus.TabIndex = 10
		'
		'cmbTechnicians
		'
		Me.cmbTechnicians.FormattingEnabled = True
		Me.cmbTechnicians.Location = New System.Drawing.Point(95, 65)
		Me.cmbTechnicians.Name = "cmbTechnicians"
		Me.cmbTechnicians.Size = New System.Drawing.Size(121, 21)
		Me.cmbTechnicians.TabIndex = 11
		'
		'tbID
		'
		Me.tbID.Location = New System.Drawing.Point(95, 12)
		Me.tbID.Name = "tbID"
		Me.tbID.ReadOnly = True
		Me.tbID.Size = New System.Drawing.Size(121, 20)
		Me.tbID.TabIndex = 6
		'
		'DetailsView
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(226, 173)
		Me.Controls.Add(Label1)
		Me.Controls.Add(Me.cmbTechnicians)
		Me.Controls.Add(lblAssignedOn)
		Me.Controls.Add(Me.dtpAssignedOn)
		Me.Controls.Add(lblCompletedOn)
		Me.Controls.Add(Me.dtpCompletedOn)
		Me.Controls.Add(lblID)
		Me.Controls.Add(Me.tbID)
		Me.Controls.Add(lblName)
		Me.Controls.Add(Me.tbName)
		Me.Controls.Add(lblStatus)
		Me.Controls.Add(Me.cmbStatus)
		Me.Name = "DetailsView"
		Me.Text = "DetailsView"
		Me.ResumeLayout(False)
		Me.PerformLayout()

	End Sub
	Friend WithEvents dtpAssignedOn As System.Windows.Forms.DateTimePicker
	Friend WithEvents dtpCompletedOn As System.Windows.Forms.DateTimePicker
	Friend WithEvents tbName As System.Windows.Forms.TextBox
	Friend WithEvents cmbStatus As System.Windows.Forms.ComboBox
	Friend WithEvents cmbTechnicians As System.Windows.Forms.ComboBox
	Friend WithEvents tbID As System.Windows.Forms.TextBox
End Class

Open in new window

Produces the following output -Initial startup.Right-clicking on a row will select if (if not selected) and bring up the context menu.Let's change the Status to Completed.Status update on the DetailView and the datagrid simultaneously.That being said, I have noticed some erroneous behaviour when you initially start-up the form and try to do the same with the last (and sometimes second to last row).  It will show the changes once you close the detail form and choose another row (if you go back to the last row and alter it again both forms show the change immediately).  The issue with updating the grid is easily solved by refreshing the binding source when you exit the detail view.

-saige-
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Article by: jpaulino
XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now