DataSource切り替え時の選択状態の保持について

タグの編集
投稿者 まりもん  (社会人) 投稿日時 2020/9/9 11:45:17
FormにComboBoxを2つ用意し、下記ソースのようにCombobox1の選択によってComboBox2のDataSourceを切り替えています。

Public Class Form1

    Dim d1 As Integer() = {1, 2, 3, 4, 5}
    Dim d2 As Integer() = {50, 40, 30, 20, 10}


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ComboBox1.Items.Add("データ1")
        ComboBox1.Items.Add("データ2")
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
        If ComboBox1.SelectedIndex = 0 Then
            ComboBox2.DataSource = d1
        Else
            ComboBox2.DataSource = d2
        End If
    End Sub

    Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged
        Console.WriteLine(ComboBox2.SelectedIndex)
    End Sub

End Class


この時、
ComboBox1でデータ1を選択し、ComboBox2の値「4」を選択
次にComboBox1でデータ2を選択し、ComboBox2の値「40」を選択、
再度ComboBox1でデータ1を選択した場合、最初に選んだComboBox2の項目「4」が自動で選択されます。

データソースが切り替わることにより選択状態もリセットされているというのが当方で考えていたことなのですが、実際の動作が異なります。

このようなデータソースを切り替えたときの選択状態の保持はDataGridViewでも確認しています。
このデータソースを切り替えたときの選択状態を保持しないようにするには何か方法があるのでしょうか?
投稿者 ぴよ  (社会人) 投稿日時 2020/9/9 12:02:27
最初の項目を強制的に表示したいのであれば、以下のコードを追加するとどうでしょう。
ComboBox2.SelectedIndex = 0
投稿者 (削除されました)  () 投稿日時 2020/9/9 12:33:28
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/9/9 12:42:53
> データソースが切り替わることにより選択状態もリセットされているというのが

「どのような一覧を表示するか」という情報と
「データソースのどのアイテムを選択しているか」は別管理です。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Label1.Text = If(BindingContext.Contains(d1), _
        If(BindingContext(d1).Position < 0, "(nothing)", BindingContext(d1).Current), _
        "未割当").ToString()
    Label2.Text = If(BindingContext.Contains(d2), _
        If(BindingContext(d2).Position < 0, "(nothing)", BindingContext(d2).Current), _
        "未割当").ToString()
End Sub



> データソースが切り替わることにより選択状態もリセットされているというのが
同一インスタンスである限りリセットされません。
下記を実行してみると、体感できると思います。

Private d1 As Integer() = {1, 2, 3, 4, 5}
Private d2 As Integer() = {50, 40, 30, 20, 10}

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ComboBox1.Items.Add("データ1")
    ComboBox1.Items.Add("データ2")
    ComboBox2.DataSource = Nothing
    ComboBox3.DataSource = d1
    ComboBox4.DataSource = d2
End Sub

Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
    If ComboBox1.SelectedIndex = 0 Then
        ComboBox2.DataSource = d1
    Else
        ComboBox2.DataSource = d2
    End If
    'ComboBox2.SelectedIndex = If(ComboBox2.Items.Count = 0, -1, 0) 
End Sub
投稿者 まりもん  (社会人) 投稿日時 2020/9/9 13:02:10
返答ありがとうございます。

>ぴよさん

ComboBox2.SelectedIndex = 0
にて結果的に選択されているアイテムは戻るのですが、その際にSelectedIndexChangedイベントが発生してしまいます。
質問には書いてなかったので申し訳ないのですが、SelectedIndexChangedイベントにて処理していることがあった為、少し問題がありました。

>魔界の仮面弁士さん

BindingContextというものが初耳でしたので、そちらで選択状態が管理されているということを知りませんでした。
DataSourceを設定する前に
If BindingContext.Contains(d1) Then BindingContext(d1).Position = -1
ComboBox2.DataSource = d1

といった形で、選択状態をリセットすることができました。