두 개의 콤보 상자가있는 Windows 양식이 있습니다. 각 콤보 상자의 SelectedValue
속성은 간단한 DTO의 속성에 바인딩 된 데이터입니다. 각 콤보 상자의 옵션은 모델 객체 목록에서 가져옵니다. DTO를 업데이트하기 위해 양식의 컨트롤 만 필요합니다. DTO의 속성을 프로그래밍 방식으로 수정하고 해당 컨트롤이 업데이트되는지 확인할 필요가 없습니다. 즉, 단방향 (컨트롤 -> 소스) 데이터 바인딩 만 작동하면됩니다.왜 Winforms 계단식 콤보 상자 집합에 바인딩하면 루트 콤보 상자의 값이 제대로 설정되지 않습니까?
사용자가 첫 번째 콤보 상자의 값을 변경하면 두 번째 콤보 상자의 옵션이 완전히 변경됩니다. 첫 번째 콤보 상자가 변경 될 때마다
- , NRE가 생성 프레임 워크를 데이터 바인딩에 의해 삼켰을 : 그러나, 나는이 발생하거나 해결하는 방법을 왜 알아낼 수 없습니다이 설정 두 가지 문제로 실행 한 (Visual Studio IDE의 직접 실행 창에 표시되는 것을 볼 수 있습니다.)이 팁은 올바르게 설정되지 않았다는 것을 알려줍니다. 두 번째 콤보 상자 또는 다른 관련되지 않은 데이터 바인딩 된 컨트롤 (콤보 상자 또는 기타)을 변경하면 NRE가 생성되지 않습니다.
- 위의 NRE를 생성 한 후 첫 번째 콤보 상자가 변경 될 때마다 두 번째 콤보 상자가 성공적으로로드되지만 첫 번째 콤보 상자의 선택한 인덱스는 -1로 다시 설정됩니다. 데이터 바인딩의 "밀어 넣기"이벤트가 컨트롤을 업데이트하기 위해 발생하고 첫 번째 콤보 상자를 지원하는 내 DTO 속성의 값이 NULL/Nothing으로 재설정되기 때문에 이것이 원인이라고 생각됩니다.
이러한 일이 발생하는 이유에 대해 아는 사람이 있습니까? 나는 위의 두 가지 문제를 보여주는 내 문제를 조롱했다. 또한 다른 콤보 상자에 대한 종속성이없는 콤보 상자가 정상적으로 작동하는지 확인하기위한 위생 상태 검사와 마찬가지로 첫 번째 항목과 상관이없는 세 번째 콤보 상자를 추가했습니다.
이 코드는 Visual Basic Windows Forms 프로젝트 (3.5 Framework)의 기본 Form1 클래스에 대한 코드로 붙여 넣습니다.
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Windows.Forms
Public Class Form1
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.cboA = New System.Windows.Forms.ComboBox()
Me.cboB = New System.Windows.Forms.ComboBox()
Me.cboC = New System.Windows.Forms.ComboBox()
Me.SuspendLayout()
'
'cboA
'
Me.cboA.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.cboA.FormattingEnabled = True
Me.cboA.Location = New System.Drawing.Point(120, 25)
Me.cboA.Name = "cboA"
Me.cboA.Size = New System.Drawing.Size(121, 21)
Me.cboA.TabIndex = 0
'
'cboB
'
Me.cboB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.cboB.FormattingEnabled = True
Me.cboB.Location = New System.Drawing.Point(120, 77)
Me.cboB.Name = "cboB"
Me.cboB.Size = New System.Drawing.Size(121, 21)
Me.cboB.TabIndex = 1
'
'cboC
'
Me.cboC.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.cboC.FormattingEnabled = True
Me.cboC.Location = New System.Drawing.Point(120, 132)
Me.cboC.Name = "cboC"
Me.cboC.Size = New System.Drawing.Size(121, 21)
Me.cboC.TabIndex = 2
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(284, 262)
Me.Controls.Add(Me.cboC)
Me.Controls.Add(Me.cboB)
Me.Controls.Add(Me.cboA)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
Friend WithEvents cboA As System.Windows.Forms.ComboBox
Friend WithEvents cboB As System.Windows.Forms.ComboBox
Friend WithEvents cboC As System.Windows.Forms.ComboBox
Private _DataObject As MyDataObject
Private _IsInitialized As Boolean = False
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_DataObject = New MyDataObject()
BindControls()
End Sub
Private Sub BindControls()
LoadComboA(cboA)
Dim cmbABinding As New Binding("SelectedValue", _DataObject, "ValueA", True, DataSourceUpdateMode.OnPropertyChanged)
cboA.DataBindings.Add(cmbABinding)
Dim cmbBBinding As New Binding("SelectedValue", _DataObject, "ValueB", True, DataSourceUpdateMode.OnPropertyChanged)
cboB.DataBindings.Add(cmbBBinding)
LoadComboC(cboC)
Dim cmbCBinding As New Binding("SelectedValue", _DataObject, "ValueC", True, DataSourceUpdateMode.OnPropertyChanged)
cboC.DataBindings.Add(cmbCBinding)
End Sub
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
_IsInitialized = True
cboA.SelectedIndex = 0
cboC.SelectedIndex = 0
End Sub
Private Sub ComboA_SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs) Handles cboA.SelectedValueChanged
If _IsInitialized Then
LoadComboB(cboB, cboA.SelectedValue.ToString())
cboB.SelectedIndex = 0
End If
End Sub
Private Sub LoadComboA(ByVal cmbBox As ComboBox)
Dim someData As New Dictionary(Of String, String)()
someData.Add("Value1", "Text 1")
someData.Add("Value2", "Text 2")
someData.Add("Value3", "Text 3")
cmbBox.DataSource = someData.ToList()
cmbBox.DisplayMember = "Value"
cmbBox.ValueMember = "Key"
End Sub
Private Sub LoadComboB(ByVal cmbBox As ComboBox, ByVal selector As String)
Dim someSubData As New Dictionary(Of String, String)()
Select Case selector
Case "Value1"
someSubData.Add("SubValue1", "Value1 - Sub Text 1")
someSubData.Add("SubValue2", "Value1 - Sub Text 2")
someSubData.Add("SubValue3", "Value1 - Sub Text 3")
Case "Value2"
someSubData.Add("SubValue4", "Value2 - Sub Text 4")
someSubData.Add("SubValue5", "Value2 - Sub Text 5")
someSubData.Add("SubValue6", "Value2 - Sub Text 6")
Case "Value3"
someSubData.Add("SubValue7", "Value3 - Sub Text 7")
someSubData.Add("SubValue8", "Value3 - Sub Text 8")
someSubData.Add("SubValue9", "Value3 - Sub Text 9")
End Select
cmbBox.DataSource = someSubData.ToList()
cmbBox.DisplayMember = "Value"
cmbBox.ValueMember = "Key"
End Sub
Private Sub LoadComboC(ByVal cmbBox As ComboBox)
Dim someData As New Dictionary(Of String, String)()
someData.Add("Value100", "Text 100")
someData.Add("Value101", "Text 101")
cmbBox.DataSource = someData.ToList()
cmbBox.DisplayMember = "Value"
cmbBox.ValueMember = "Key"
End Sub
End Class
Public Class MyDataObject ' DTO class
Private _ValueA As String
Public Property ValueA() As String
Get
Return _ValueA
End Get
Set(ByVal value As String)
_ValueA = value
End Set
End Property
Private _ValueB As String
Public Property ValueB() As String
Get
Return _ValueB
End Get
Set(ByVal value As String)
_ValueB = value
End Set
End Property
Private _ValueC As String
Public Property ValueC() As String
Get
Return _ValueC
End Get
Set(ByVal value As String)
_ValueC = value
End Set
End Property
End Class
이 질문은 종속 콤보 상자 집합, 개체에 바인딩 된 데이터로 인해 하나 이상의 콤보 상자의 기본 기능이 실패하는 방식을 설명하려고합니다. 계단식/종속 형 콤보 상자는 매우 일반적입니다. 데이터 바인딩 또한 일반적인 관행입니다. 나는이 상황이 매우 좁은 것은 아니라고 생각한다. 이 질문을 다시 입력하십시오. –
동의합니다. 다시여십시오. – OneFineDay