Click here to Skip to main content
13,550,613 members
Rate this:
 
Please Sign up or sign in to vote.
I have a complex project that utilizes various inherited forms to reference different tables from a strongly-typed dataset (InventoryDataSet). The base form contains all of the common controls and components, and each inherited form fills in the details applicable to the datatable it maintains. In order to simplify the coding necessary for each form, I have created interfaces to enable the base form to manipulate data in each inherited form and its components.

One of the interfaces I use implements a component class (TableInterface) that holds references to its datatable’s BindingSource and TableAdapter and the derived (owner) form. The component uses reflection to access the tableadapter’s methods (loading, updating, etc) along with data validation control and errorprovider methods. That part was written as a workaround for the limitations presented by Microsoft because of the lack of a base TableAdapter class, and it works great!

The problem I am having revolves around the form designer and an interfaced component's property. That is, when I attempt to set the property to the system-generated bindingsource (in this case, VendorBindingSource) in the designer for an inherited form, I get the error:

Unable to cast object of type 'VendorDataTable' to type 'InventoryManager.ITableInterface'

The error stems from the conversion attempted in the last statement of sub SetTable. There, I attempt to point back to the TableInterface component from the datatable, where I have implemented ITableInterface in the user-code partial class of the InventoryDataSet’s VendorDataTable definition.

I thought that the error could be the result of some extraneous processing within the assignment, but it is a simple, single-line, get/set property definition. And the weird thing is that if I hard-code the assignment within the derived form (immediately following the sub New’s call to InitializeComponent), it all works as expected!

Does anybody have any ideas how to fix/workaround this situation? I would really prefer to use the designer for the property assignment, rather than having to hard-code into each form (although I will do that if necessary...).

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

Side Note: At one time this arrangement was indeed working, but I was having trouble with the dynamic reformatting of the UI, so I had to redesign the base form a number of times. I also tried to organize the project directory by putting forms in one subfolder, common controls in another, etc; while doing so I moved the dataset definition to a subfolder, and it seems to me that the problem started at that point (I have since moved the dataset back to the project’s main folder, cleaned and rebuilt the solution – to no avail). I do not know if this was a factor but I thought that I should mention it.

Off-Topic Request: Can anyone tell me how to limit the designer propertygrid dropdown for the TableInterface’s TableAdapter property to just tableadapters (eg: components with names ending in “TableAdapter”, or even just components)? By default, the dropdown apparently includes all components and controls in the form!

I am using:
Microsoft Visual Basic 2010 Express - ENU Service Pack 1 - Version 10.0.40219.1 SP1Rel
Microsoft .NET Framework - Version 4.5.51209 SP1Rel
Hotfix for Microsoft Visual Basic 2010 Express - ENU (KB2635973)

with Vista Home Premium Service Pack 2 (Version 6.0.6002) x64.

Thank you in advance for any help you can give!

What I have tried:

I have searched the internet, but I have found nothing that bears on my situation. I have also tried to mutate my code but I just end up going down the rabbit hole over and over...
Posted 10-Nov-17 16:03pm

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy |
Web01-2016 | 2.8.180515.1 | Last Updated 10 Nov 2017
Copyright © CodeProject, 1999-2018
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100