Sam Makin
Sam Makin

Reputation: 1556

ComboBox with Binding on SeclectedItem unable to change selection

I have a simple form that uses DataBinding to bind to a collection of objects. Initially I don't want the ComboBox to display a selection, so I set its selected index to -1. However when the ComboBox becomes selected I am unable to deselect it without picking a value.

How can I deselect the ComboBox (select other controls) without picking a value?

To recreate, create a new winform, add a ComboBox and a TextBox, then use this code:

Imports System.Collections.Generic

Public Class Form1

    Public Property f As Person

    Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Dim db As New People
        ' ComboBox1.CausesValidation = False
        ComboBox1.DataSource = db
        ComboBox1.DisplayMember = "Name"
        ComboBox1.DataBindings.Add("SelectedItem", Me, "f", False, DataSourceUpdateMode.OnPropertyChanged)
        ComboBox1.SelectedIndex = -1
    End Sub

End Class

Public Class Person
    Public Property Name As String
End Class

Public Class People
    Inherits List(Of Person)

    Public Sub New()
        Me.Add(New Person With {.Name = "Dave"})
        Me.Add(New Person With {.Name = "Bob"})
        Me.Add(New Person With {.Name = "Steve"})
    End Sub
End Class

When the form starts the ComboBox should be selected and it is not possible to select the TextBox.

I have found that switching CausesValidation to False on the ComboBox fixes the problem, but it breaks the DataBinding.

Upvotes: 0

Views: 67

Answers (1)

Sam Makin
Sam Makin

Reputation: 1556

Found a solution! (Thanks Ivan!)

If the ComboBox as a SelectedIndex of -1 when it is Validating disable the binding temporarily.

        AddHandler ComboBox1.Validating, AddressOf DisableBindingWhenNothingSelected
        AddHandler ComboBox1.Validated, AddressOf DisableBindingWhenNothingSelected

    ''' <summary>
    ''' Temporarily disables binding when nothing is selected.  
    ''' </summary>
    ''' <param name="sender">Sender of the event.</param>
    ''' <param name="e">Event arguments.</param>
    ''' <remarks>A list bound ComboBox (and more generically ListControl) cannot be deselected, 
    ''' because CurrencyManager does not allow setting the Position to -1 when the underlying list Count is > 0. 
    ''' This should be bound to the Validating and Validated events of all ComboBoxes that have an initial SelectedIndex of -1.</remarks>
    Protected Sub DisableBindingWhenNothingSelected(sender As Object, e As EventArgs)
        Dim cb As ComboBox = DirectCast(sender, ComboBox)
        If cb.SelectedIndex = -1 Then
            If (cb.DataBindings.Count = 0) Then Exit Sub
            If cb.DataBindings(0).DataSourceUpdateMode = DataSourceUpdateMode.Never Then
                cb.DataBindings(0).DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged
            Else
                cb.DataBindings(0).DataSourceUpdateMode = DataSourceUpdateMode.Never
            End If
        End If
    End Sub

Upvotes: 1

Related Questions