2017-04-19 92 views
0

对于使用Visual Basic .NET的Windows Forms中的数据绑定,我仍然很陌生,但试图熟悉它。我试图寻找这方面的信息,但无济于事。如何在DataGridView绑定时在BindingList中编辑空值?

我想建立双向一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实例可以进入到。 但是,其中一些插槽可能为空,可能需要稍后填写或清除。表中的行数由其他地方输入的数字指定,因此用户无法随时添加或删除行;他们必须与所给的空间一起工作。

我在这个当前的尝试是有结合到BindingList(Of MyListElementClass),其中其大小总是等于可用时隙和空的时隙的数目是由空元素表示的DataGridView控制。但是,我发现如果我在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,并且有一行包含一些示例值,总共为三行。我可以编辑第二行和第三行,但不是第一行(我输入的任何值立即消失)。

再一次,在这个完全陌生的领域里,请耐心等待。如果我无法得到这个工作,那么我会放弃这个想法,然后回到手动设置和检索数据,就像我以前一直做的那样。

+0

不能重播,但大多数'SetUpTableDataBinding'代码不需要。 a)你不需要创建一个List来填充一个BindingList b)你不需要一个BindingList的BindingSource。 c)DGV将从源获取列数据类型,即使这样“PropertyA”就是所有你需要的反射来获取名称。 – Plutonix

+0

@Plutonix我在你的观点a)和b)中提到的代码是从我的问题中链接的答案开始的。我知道你可以将一个DataGridView直接绑定到一个BindingList,但我的印象是最好总是绑定到一个BindingSource(或者不是?)。为了响应c)点,我设置了每列的DataPropertyName,这样我就可以按照指定的顺序向用户显示更友好的列名,所以如果稍后更改属性名称,那么重构也会更容易。 –

+0

'DataPropertyName'没有任何东西可以让用户看到什么。它是要绑定到的列的名称。 – Plutonix

回答

1

无法编辑空值,将其替换为空字符串,而我认为您会发现它将按预期工作。

+0

这不会为我编译,因为给定;你的意思是['IsDBNull'](https://msdn.microsoft.com/en-us/library/tckcces5(v = vs.90).aspx)函数?但即使做了这样的调整,与我已有的相比,这些代码也没有任何效果。 –

+0

对不起,我写这篇文章的时候已经很晚了,而且我很累。是的,IsDBNull。没有影响?好的...我现在仔细看看它,我已经休息了......大声笑... –

+0

你可以发布MyListElementClass的代码吗? –

相关问题