我仍然对使用Visual Basic .NET的Windows窗体中的数据绑定非常新,但试图熟悉它。我已经尝试过查找有关这方面的信息,但无济于事。
我想设置一个DataGridView
控件和一个对象列表之间的双向绑定(假设它们是一个名为MyListElementClass
的虚构类型),其方式类似于我在this answer中看到了另一个问题。以下是MyListElementClass
的实施,位于名为 MyListElementClass.vb 的文件中:
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
<Serializable>
Public NotInheritable Class MyListElementClass
Implements INotifyPropertyChanged
Implements IMyListElementClass
#Region "Fields"
Private _a As UShort
Private _b As Double
Private _c, _d, _e As Boolean
' End fields region.
#End Region
#Region "INotifyPropertyChanged implementation"
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
' End INotifyPropertyChanged implementation region.
#End Region
#Region "IMyListElementClass implementation"
Public Property PropertyA As UShort Implements IMyListElementClass.PropertyA
Get
Return _a
End Get
Set(value As UShort)
If _a <> value Then
_a = value
NotifyPropertyChanged()
End If
End Set
End Property
Public Property PropertyB As Double Implements IMyListElementClass.PropertyB
Get
Return _b
End Get
Set(value As Double)
If _b <> value Then
_b = value
NotifyPropertyChanged()
End If
End Set
End Property
Public Property PropertyC As Boolean Implements IMyListElementClass.PropertyC
Get
Return _c
End Get
Set(value As Boolean)
If _c <> value Then
_c = value
NotifyPropertyChanged()
End If
End Set
End Property
Public Property PropertyD As Boolean Implements IMyListElementClass.PropertyD
Get
Return _d
End Get
Set(value As Boolean)
If _d <> value Then
_d = value
NotifyPropertyChanged()
End If
End Set
End Property
Public Property PropertyE As Boolean Implements IMyListElementClass.PropertyE
Get
Return _e
End Get
Set(value As Boolean)
If _e <> value Then
_e = value
NotifyPropertyChanged()
End If
End Set
End Property
' End IMyListElementClass implementation region.
#End Region
#Region "Constructors"
Public Sub New()
PropertyA = 0
PropertyB = 0
PropertyC = False
PropertyD = False
PropertyE = False
End Sub
Public Sub New(a As UShort, b As Double, c As Boolean, d As Boolean, e As Boolean)
Me.PropertyA = a
Me.PropertyB = b
Me.PropertyC = c
Me.PropertyD = d
Me.PropertyE = e
End Sub
Public Sub New(other As IMyListElementClass)
If other Is Nothing Then Throw New ArgumentNullException(NameOf(other))
CopyFrom(other)
End Sub
' End constructors region.
#End Region
#Region "Methods"
Public Sub CopyFrom(other As IMyListElementClass)
If other Is Nothing Then Throw New ArgumentNullException(NameOf(other))
With other
PropertyA = .PropertyA
PropertyB = .PropertyB
PropertyC = .PropertyC
PropertyD = .PropertyD
PropertyE = .PropertyE
End With
End Sub
' End methods region.
#End Region
End Class
这里的想法是DataGridView
控件将显示可以输入MyListElementClass
实例的可用“槽”(行)列表。 但是,其中一些插槽可能为空,可能需要填写或稍后清除。表中的行数由其他地方输入的数字指定,因此用户无法添加或删除飞行中的行;他们必须使用给定的空间。
我目前的尝试是将DataGridView
控件绑定到BindingList(Of MyListElementClass)
,其中其大小始终等于可用插槽的数量,空插槽由null元素表示。但是,我发现如果我在BindingList(Of MyListElementClass)
中存在这些空值,那么这些行不能由用户在绑定到它的DataGridView
控件中编辑,我不确定如何处理这件事。
我正在尝试在我的用户控件中执行的示例,其中包含DataGridView
(此处名为dgvDataGridView
,并且已通过设计器设置了列):
Public Class MyUserControl
Private _myBindingList As BindingList(Of MyListElementClass)
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
dgvDataGridView.AutoGenerateColumns = False ' Columns already created through the Visual Studio designer with the ordering and header text I want.
SetUpTableDataBinding()
End Sub
Private Sub SetUpTableDataBinding()
colA.DataPropertyName = NameOf(MyListElementClass.PropertyA)
colB.DataPropertyName = NameOf(MyListElementClass.PropertyB)
colC.DataPropertyName = NameOf(MyListElementClass.PropertyC)
colD.DataPropertyName = NameOf(MyListElementClass.PropertyD)
colE.DataPropertyName = NameOf(MyListElementClass.PropertyE)
Dim initialList As New List(Of MyListElementClass)(Enumerable.Repeat(Of MyListElementClass)(Nothing, 1)) ' First row will contain a null value, and hence be "empty".
_myBindingList = New BindingList(Of MyListElementClass)(initialList)
Dim source = New BindingSource(_myBindingList, Nothing)
dgvDataGridView.DataSource = source
' Some test data for data binding.
_myBindingList.AddNew() ' Adds a new MyListElementClass instance with default property values.
_myBindingList.Add(New MyListElementClass(2345, 7.4, False, True, False)) ' Just some sample values.
End Sub
End Class
加载此用户控件后,我可以看到一个空行,一行显示MyListElementClass
的默认值,一行显示一些样本值,共计三行。我可以编辑第二行和第三行,但不能编辑第一行(我输入的任何值都会立即消失)。
再次,在这里完全不熟悉的领域,请耐心等待。如果我无法解决这个问题,那么我将放弃这个想法并返回到DataGridView
单元格中手动设置和检索数据,就像我一直以来一样。
答案 0 :(得分:1)
无法编辑空值,而是用空字符串替换它们,我认为您会发现它可以按预期工作。