当DataGridView绑定到BindingList时,如何编辑BindingList中的空值?

时间:2017-04-19 20:58:03

标签: vb.net winforms data-binding datagridview

我仍然对使用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单元格中手动设置和检索数据,就像我一直以来一样。

1 个答案:

答案 0 :(得分:1)

无法编辑空值,而是用空字符串替换它们,我认为您会发现它可以按预期工作。