Login or Sign Up to become a member!

EXPERTS, INFORMATION, IDEAS & KNOWLEDGE

Social bookmarker Add this

Your profile

Search

January 2009
Mon Tue Wed Thu Fri Sat Sun
 << <   > >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

XML Feeds

Authors

« 5 Books Every Developer Should ReadMy Path to the Dark Side part 2 - The Domain Model »
The Desktop Developers Journal

VB.Net: Binding a complex interface(inherited) to a datagridview

by chrissie1


Permalink 17 Jul 2008 05:07 , Categories: Microsoft Technologies, VB.NET

Lets say I have a class teacher which inherits from a class person (hard to believe I know ;-)). And we want to bind a list of Iteachers (the interface) to a datagridview because that is the easiest way of getting things working for the datagridview. This will give a surprising (perhaps not) result.

First lets look at the Person class and IPerson interface.

  1. Public Interface IPerson
  2.     Property Name() As String
  3.     Property FirstName() As String
  4. End Interface
  5.  
  6. Public Class Person
  7.     Implements IPerson
  8.     Private _name As String
  9.     Private _firstname As String
  10.  
  11.     Public Sub New()
  12.  
  13.     End Sub
  14.  
  15.     Public Sub New(ByVal Name As String, ByVal Firstname As String)
  16.         _name = Name
  17.         _firstname = Firstname
  18.     End Sub
  19.  
  20.     Public Property Name() As String Implements IPerson.Name
  21.         Get
  22.             Return _name
  23.         End Get
  24.         Set(ByVal value As String)
  25.             _name = value
  26.         End Set
  27.     End Property
  28.  
  29.     Public Property FirstName() As String Implements IPerson.FirstName
  30.         Get
  31.             Return _firstname
  32.         End Get
  33.         Set(ByVal value As String)
  34.             _firstname = value
  35.         End Set
  36.     End Property
  37. End Class

And then the Teacher class and ITeacher interface which inherits from IPerson.

  1. Public Interface ITeacher
  2.     Inherits IPerson
  3.     Property ClassRoom() As String
  4. End Interface
  5.  
  6. Public Class Teacher
  7.     Inherits Person
  8.     Private _classroom As String
  9.  
  10.     Public Sub New()
  11.  
  12.     End Sub
  13.  
  14.     Public Sub New(ByVal name As String, ByVal FirstName As String, ByVal ClassRoom As String)
  15.         MyBase.New(Name, FirstName)
  16.         _classroom = ClassRoom
  17.     End Sub
  18.  
  19.     Public Property ClassRoom() As String
  20.         Get
  21.             Return _classroom
  22.         End Get
  23.         Set(ByVal value As String)
  24.             _classroom = value
  25.         End Set
  26.     End Property
  27. End Class

And then we bind it to the datagridview via a bindingsource. Like so

  1. Public Class Form1
  2.     Dim _bs As BindingSource
  3.  
  4.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  5.         Dim _l As New List(Of ITeacher)
  6.         _l.Add(New Teacher("t1", "f1", "A"))
  7.         _l.Add(New Teacher("t2", "f2", "B"))
  8.         _l.Add(New Teacher("t3", "f3", "C"))
  9.         _l.Add(New Teacher("t4", "f4", "D"))
  10.         _l.Add(New Teacher("t5", "f5", "E"))
  11.         _l.Add(New Teacher("t6", "f6", "F"))
  12.         _l.Add(New Teacher("t7", "f7", "G"))
  13.         _bs = New BindingSource
  14.         _bs.DataSource = _l
  15.         Me.DataGridView1.DataSource = _bs.DataSource
  16.     End Sub
  17. End Class

If we run this we will get this.

So where did the person data go?

And know watch even more closely and find the difference.

  1. Public Class Form1
  2.     Dim _bs As BindingSource
  3.  
  4.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  5.         Dim _l As New List(Of Teacher)
  6.         _l.Add(New Teacher("t1", "f1", "A"))
  7.         _l.Add(New Teacher("t2", "f2", "B"))
  8.         _l.Add(New Teacher("t3", "f3", "C"))
  9.         _l.Add(New Teacher("t4", "f4", "D"))
  10.         _l.Add(New Teacher("t5", "f5", "E"))
  11.         _l.Add(New Teacher("t6", "f6", "F"))
  12.         _l.Add(New Teacher("t7", "f7", "G"))
  13.         _bs = New BindingSource
  14.         _bs.DataSource = _l
  15.         Me.DataGridView1.DataSource = _bs.DataSource
  16.     End Sub
  17. End Class

And see the result.

Yes the fields are there. Why does this happen? Well reflection and a bug in the interface implementation. Reflection should pick up the properties from IPerson in ITeacher like it does for the class but it doesn’t so your ……. The only solution that works is either bind to teacher or (like in my case) make a private class that accepts an ITeacher and has all the properties needed).

and why in my case? Because I only pass interface between my different layers, never implmentations.

Something like this.

  1. Public Class LocalTeacher
  2.     Implements ITeacher
  3.  
  4.     Private _teacher As ITeacher
  5.     Public Sub New(ByVal Teacher As ITeacher)
  6.         _teacher = Teacher
  7.     End Sub
  8.  
  9.     Public Property Name() As String Implements IPerson.Name
  10.         Get
  11.             Return _teacher.Name
  12.         End Get
  13.         Set(ByVal value As String)
  14.             _teacher.Name = value
  15.         End Set
  16.     End Property
  17.  
  18.     Public Property FirstName() As String Implements IPerson.FirstName
  19.         Get
  20.             Return _teacher.FirstName
  21.         End Get
  22.         Set(ByVal value As String)
  23.             _teacher.FirstName = value
  24.         End Set
  25.     End Property
  26.  
  27.  
  28.     Public Property ClassRoom() As String Implements ITeacher.ClassRoom
  29.         Get
  30.             Return _teacher.ClassRoom
  31.         End Get
  32.         Set(ByVal value As String)
  33.             _teacher.ClassRoom = value
  34.         End Set
  35.     End Property
  36.  
  37.     Public ReadOnly Property Teacher() As ITeacher
  38.         Get
  39.             Return _teacher
  40.         End Get
  41.     End Property
  42. End Class

And then this for the form.

  1. Public Class Form1
  2.     Dim _bs As BindingSource
  3.  
  4.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  5.         ‘normally I would get this from the DAL
  6.         Dim _l As New List(Of ITeacher)
  7.         _l.Add(New Teacher("t1", "f1", "A"))
  8.         _l.Add(New Teacher("t2", "f2", "B"))
  9.         _l.Add(New Teacher("t3", "f3", "C"))
  10.         _l.Add(New Teacher("t4", "f4", "D"))
  11.         _l.Add(New Teacher("t5", "f5", "E"))
  12.         _l.Add(New Teacher("t6", "f6", "F"))
  13.         _l.Add(New Teacher("t7", "f7", "G"))
  14.         ‘Then I have to do this to it
  15.         Dim _l2 As New List(Of LocalTeacher)
  16.         For Each T As ITeacher In _l
  17.             _l2.Add(New LocalTeacher(T))
  18.         Next
  19.         _bs = New BindingSource
  20.         _bs.DataSource = _l2
  21.         Me.DataGridView1.DataSource = _bs.DataSource
  22.     End Sub
  23. End Class

and then of course it’s a mess to save it again ;-). Call me nuts :crazy: and tell me I should just pass the objects. But trust me I won’t. I’ll keep the interfaces and live with this kind of thing.

Need help with VB.Net? Come and ask a question in our VB.Net Forum

Leave a comment »Send a trackback » 933 views

Trackback address for this post

Trackback URL (right click and copy shortcut/link location)

No feedback yet

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
PoorExcellent
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)