【问题标题】:Why do you need to name a datatable before binding it to a dataview?为什么需要在将数据表绑定到数据视图之前为其命名?
【发布时间】:2021-05-05 11:25:42
【问题描述】:

当我绑定一个 Dataview 时,我可以将一个 DataTable 转储到其中而不会出现任何问题

Dim dtTable As New DataTable
Dim dvTable As New DataView
dvTable.Table = dtTable

这很好用。

但是在我的新项目中,我收到错误“无法绑定到没有名称的 DataTable”。尝试绑定表时;

Public Class frmInvoiceCategories
Dim intDtInvoiceRowCount As Integer = 0
Dim dtItemCategory1() As DataTable
Dim dtItemCategory2() As DataTable
Dim dvItemCategory2 As New DataView
Dim blnDtCategory2Functional As Boolean = False

Private Sub frmInvoiceCategories_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ReDim cboInvoiceItemTypeMajor(intDtInvoiceRowCount) 'resize the array to fit enough
    ReDim cboInvoiceItemTypeMinor(intDtInvoiceRowCount) 'resize the array to fit enough
    ReDim dtItemCategory2(intDtInvoiceRowCount) 'resize the array to fit enough dt
    subLoadCboItemCategory2() 'load all the item categories for the subcategory cbo    
End Sub

Private Sub subLoadCboItemCategory2()
        Dim dtItemCategory2Main As New DataTable 'create a temporary dt to check if all the columns are in this dt, then copy the dt
        dtItemCategory2Main = fnGetItemCategory2(0) 'get all item subcategories

        'check if the dt is functional
        If dtItemCategory2Main IsNot Nothing Then 'does the dt exist?
            If dtItemCategory2Main.Columns.Count > 0 Then 'does the dt have columns?
                If dtItemCategory2Main.Columns.Contains("ID") Then 'does it have an ID column?
                    If dtItemCategory2Main.Columns.Contains("Category2") Then 'does it have a dislpayname column?
                        blnDtCategory2Functional = True 'table is complete enough to run
                    Else
                        MsgBox("Data table category2 doesn't have category2 column")
                    End If
                Else
                    MsgBox("Data table category2 doesn't have ID column")
                End If
            Else
                MsgBox("Data table category2 doesn't have columns")
            End If
        Else
            MsgBox("Data table category2 is nothing")
        End If

        If blnDtCategory2Functional = True Then 'if the dt is complete
            For intIndex = 0 To intDtInvoiceRowCount Step 1 'count through all the rows in the dt
                dtItemCategory2(intIndex) = New DataTable 'create a new instance of the dt
                dtItemCategory2(intIndex) = dtItemCategory2Main 'copy the main dt
            Next
        Else 'the dt is incomplete
            MsgBox("form is unusable, closing down")
            Me.Close()
        End If
    End Sub

Private Sub cboInvoiceItemTypeMajor_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs)
dvItemCategory2.Table = dtItemCategory2(intIndex)
End Sub
End Class

为什么我突然要给表命名?对数组中的表对象的引用就在那里。 可以不给它起名字吗?

【问题讨论】:

  • 您是否知道每个DataTable 都自动与DataView 关联,可通过其DefaultView 属性访问?事实上,当您在 WinForms 应用程序中绑定 DataTable 时,您在 UI 中看到的数据实际上来自该 DataView,这就是绑定到 DataGridView 时能够对数据进行排序的方式。您需要显式创建 DataView 的唯一原因是您需要同一个表的多个视图。
  • 完全不知道这一点。对于这与在将每个表绑定到数据视图之前必须命名每个表有何关系,也有点困惑。对象的链接就在那里; 'dvItemCategory2.Table = dtItemCategory2(intIndex)' 这应该足以说明我将哪个对象绑定到 Dataview,对吧?此外,创建数据视图比需要同一张表的多个视图有更多用途;例如正确过滤和排序,因为表格无法做到这一点,还是我遗漏了什么?
  • 是的,你错过了一些东西。你错过了我的评论是如何相关的。这是相关的,因为如果您不首先创建 DataView 并且您不必创建 DataView 因为已经存在一个 DataView,那么它们就没有问题要解决。只需使用 DataTable 的 DefaultView,您的问题就会变得毫无意义。
  • 另外,在极少数情况下,您确实需要创建 DataView,只需使用将 DataTable 作为参数的构造函数即可。我可能是错的,但我很确定我之前已经使用未命名的 DataTable 做到了这一点,没有问题。
  • 如果每个数据表都有自己的数据视图,为什么我不能过滤数据表中的记录? dtItemCategory2(intIndex).rowfilter = "Category_ID=" & intCategory1_ID 给出错误“rowfilter 不是数据表的成员”,当我使用数据视图时不会发生这种错误。如果您有耐心,我仍然有兴趣了解为什么我需要为每个表设置一个名称,这对我来说似乎有点多余,因为只有 1 个具有该引用的对象(dtItemCategory2(intIndex)),有什么意义命名它?为什么不将其名称设置为 dtItemCategory2(intIndex)?

标签: vb.net data-binding dataview


【解决方案1】:

正如我一直说的,DataTable 已经有一个 DataView 与之关联,所以只需使用它。据我从那段有点狡猾的代码中可以看出,你应该可以改变这个:

Dim dvItemCategory2 As New DataView

到这里:

Dim dvItemCategory2 As DataView

还有这个:

dvItemCategory2.Table = dtItemCategory2(intIndex)

到这里:

dvItemCategory2 = dtItemCategory2(intIndex).DefaultView

编辑:

关于问题所指的具体问题,我不知道您是如何做到这一点的,因为我只是查看了 DataView.Table 属性的源代码,它看起来像这样:

[RefreshProperties(RefreshProperties.All)]
[ResDescription("DataViewTableDescr")]
[DefaultValue(null)]
[TypeConverter(typeof (DataTableTypeConverter))]
[ResCategory("DataCategory_Data")]
public DataTable Table
{
  get => this.table;
  set
  {
    Bid.Trace("<ds.DataView.set_Table|API> %d#, %d\n", this.ObjectID, value != null ? value.ObjectID : 0);
    if (this.fInitInProgress && value != null)
    {
      this.delayedTable = value;
    }
    else
    {
      if (this.locked)
        throw ExceptionBuilder.SetTable();
      if (this.dataViewManager != null)
        throw ExceptionBuilder.CanNotSetTable();
      if (value != null && value.TableName.Length == 0)
        throw ExceptionBuilder.CanNotBindTable();
      if (this.table == value)
        return;
      this.dvListener.UnregisterMetaDataEvents();
      this.table = value;
      if (this.table != null)
        this.dvListener.RegisterMetaDataEvents(this.table);
      this.SetIndex2("", DataViewRowState.CurrentRows, (IFilter) null, false);
      if (this.table != null)
        this.OnListChanged(new ListChangedEventArgs(ListChangedType.PropertyDescriptorChanged, (PropertyDescriptor) new DataTablePropertyDescriptor(this.table)));
      this.OnListChanged(DataView.ResetEventArgs);
    }
  }
}

这个讨论的相关部分是这样的:

if (value != null && value.TableName.Length == 0)
  throw ExceptionBuilder.CanNotBindTable();

我不确定为什么使用没有名称的 DataTable 会出现问题 - 将 DataTable 作为参数的构造函数没有这样的限制 - 但很明显你不能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-12
    • 2021-11-25
    • 1970-01-01
    • 2019-12-18
    • 2017-04-18
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    相关资源
    最近更新 更多