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.
Заранее благодарю вас за любую помощь, которую вы можете оказать!
Что я уже пробовал:
Я искал в интернете, но не нашел ничего, что имело бы отношение к моей ситуации. Я также пытался мутировать свой код, но в конечном итоге я просто спускаюсь в кроличью нору снова и снова...