GRCook Ответов: 0

Vb.net 2010: не удается привести объект к реализованному типу в конструкторе


У меня есть сложный проект, который использует различные унаследованные формы для ссылки на различные таблицы из строго типизированного набора данных (InventoryDataSet). Базовая форма содержит все общие элементы управления и компоненты, и каждая унаследованная форма заполняет сведения, применимые к поддерживаемой ею таблице данных. Чтобы упростить кодирование, необходимое для каждой формы, я создал интерфейсы, позволяющие базовой форме манипулировать данными в каждой унаследованной форме и ее компонентах.

Один из интерфейсов, которые я использую, реализует класс компонентов (TableInterface), который содержит ссылки на его datatable BindingSource и TableAdapter, а также производную (owner) форму. Компонент использует отражение для доступа к методам tableadapter (загрузка, обновление и т. д.) наряду с методами управления проверкой данных и errorprovider. Эта часть была написана как обходной путь для ограничений, представленных Microsoft из-за отсутствия базового класса TableAdapter, и она отлично работает!

Проблема, с которой я сталкиваюсь, вращается вокруг конструктора форм и свойства сопряженного компонента. То есть, когда я пытаюсь установить свойство в системный bindingsource (в данном случае VendorBindingSource) в конструкторе для унаследованной формы, я получаю ошибку:

Невозможно привести объект типа 'VendorDataTable' к типу 'InventoryManager.ITableInterface'

Ошибка возникает из-за преобразования, предпринятого в последнем операторе sub SetTable. Там я пытаюсь указать обратно на компонент TableInterface из datatable, где я реализовал ITableInterface в частичном классе пользовательского кода определения VendorDataTable InventoryDataSet.

Я думал, что ошибка может быть результатом какой-то посторонней обработки внутри задания, но это простое, однострочное определение свойства get/set. И самое странное, что если я жестко закодирую назначение в производной форме (сразу после вызова sub New Для InitializeComponent), то все будет работать так, как ожидалось!

Есть ли у кого-нибудь идеи, как исправить/обойти эту ситуацию? Я бы действительно предпочел использовать конструктор для назначения свойств, а не жестко кодировать каждую форму (хотя я сделаю это, если это необходимо...).

Public Class TableInterface
  Inherits Component

  Public Property BindingSource As BindingSource
	Get
	  BindingSource = _BindingSource
	End Get
	Set(value As BindingSource)
	  _BindingSource = value
	  Me.SetTable()
	End Set
  End Property
  Private WithEvents _BindingSource As BindingSource

  Public ReadOnly Property DataSet As DataSet
	Get
	  DataSet = CType(_BindingSource.DataSource, DataSet)
	End Get
  End Property

  Public Property Owner As ITableInterfaceForm
	Get
	  Owner = _Owner
	End Get
	Set(value As ITableInterfaceForm)
	  _Owner = value
	  If _Owner IsNot Nothing Then _Owner.TableInterface = Me
	End Set
  End Property
  Private _Owner As ITableInterfaceForm

  Public Property TableAdapter As Component
	Get
	  TableAdapter = _TableAdapter
	End Get
	Set(value As Component)
	  _TableAdapter = value
	  _TableAdapterType = value.GetType
	End Set
  End Property
  Private _TableAdapter As Component
  Private _TableAdapterType As Type

  Public Sub SetTable() Handles _BindingSource.DataMemberChanged, _BindingSource.DataSourceChanged
	Dim dataSet As DataSet = Me.DataSet
	If dataSet Is Nothing OrElse _BindingSource.DataMember Is Nothing Then _Table = Nothing : Exit Sub
	_Table = CType(_BindingSource.DataSource, DataSet).Tables(Me.TableName)
	If _Table IsNot Nothing Then CType(_Table, ITableInterface).TableInterface = Me
  End Sub 
  Private WithEvents _Table As DataTable

#Region " TableAdapter Methods " …
#End Region

#Region " Table/ErrorProvider Methods " …
#End Region

End Class



Public Interface ITableInterface

  Property TableInterface As TableInterface
  Sub ValidateColumn(e As DataColumnChangeEventArgs)

End Interface



Public Interface ITableInterfaceForm

  Property TableInterface As TableInterface

End Interface



Partial Class InventoryDataSet

  Partial Class VendorDataTable
    Implements InventoryManager.ITableInterface

    Public Property TableInterface As TableInterface Implements ITableInterface.TableInterface

    Friend Sub ValidateColumn(e As DataColumnChangeEventArgs) Implements ITableInterface.ValidateColumn
      …
    End Sub

  End Class

End Class

Примечание: в свое время эта схема действительно работала, но у меня были проблемы с динамическим переформатированием пользовательского интерфейса, поэтому мне пришлось несколько раз переделывать базовую форму. Я также попытался организовать каталог проекта, поместив формы в одну подпапку, общие элементы управления в другую и т. д.; При этом я переместил определение набора данных в подпапку, и мне кажется, что проблема началась именно с этого момента (с тех пор я переместил набор данных обратно в основную папку проекта, очистил и перестроил решение – безрезультатно). Я не знаю, было ли это фактором, но я подумал, что должен упомянуть об этом.

Запрос вне темы: может ли кто-нибудь сказать мне, как ограничить раскрывающийся список designer propertygrid для свойства TableAdapter TableInterface только tableadapters (например, компоненты с именами, заканчивающимися на “TableAdapter”, или даже просто компоненты)? По умолчанию выпадающий список, по-видимому, включает в себя все компоненты и элементы управления в форме!

Я использую:
Microsoft Visual Basic 2010 Express - ENU Service Pack 1 - версия 10.0.40219.1 SP1Rel
Microsoft .NET Framework - версия 4.5.51209 SP1Rel
Исправление для Microsoft Visual Basic 2010 Express - ENU (KB2635973)

с Vista Home Premium Service Pack 2 (версия 6.0.6002) x64.

Заранее благодарю вас за любую помощь, которую вы можете оказать!

Что я уже пробовал:

Я искал в интернете, но не нашел ничего, что имело бы отношение к моей ситуации. Я также пытался мутировать свой код, но в конечном итоге я просто спускаюсь в кроличью нору снова и снова...

0 Ответов