Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Design Time / July 2004

Tip: Looking for answers? Try searching our database.

Problems with IsupportInitialize and CodeDom

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Dennes Torres - 18 Jul 2004 22:48 GMT
Hi !
I created a new component for my project. One of the properties of this
component is a collection of a class created by me, I called this class
"UmaTabela"

The class (each element in collection) has two properties, one of them is
another class, created by me. I called this class as "Mapeamento".

I used desinertimeserializationvisibility in collection property, and I
created a typeConverter to return instance descriptor for both, "UmaTabela"
class and "Mapeamento" class.

The problems started because "Mapeamento" class needs a initialization
sequence, so I implemented IsupportInitialize.

But VS didn't recognize the implementation of IsupportInitialize. VS
serialize the class and it's properties in the code, but didn't make the
calls for beginInit and endInit. I think this is because the class is inside
another class that's inside a collection.

To solve this problem I tried to create a custom codeDomSerializer to add
BeginInit and EndInit calls. After some trys the most closely I get is to
put the custom serializer in UmaTabela class. The problem is that Mapeamento
variable is created as a local variable inside initializeComponent and the
custom serializer generates a "me." keyword in front of method calls, like
this "me.mapeamento1.begininit", so this doesn't work because mapeamento1 is
local variable, not form variable.

So, some questions at this point :

A) Is there any other way to expose IsupportInitialize in this case without
create a custom codeDom serializer ? How to force this interface to be
regonized by VS ?

B) How to control if the components variables will be generated in form
level or in initializeComponent level ?

C) How to take out that "Me." keyword generated by the custom codeDom
serializer ?

P.S. : When Mapeamento class inherits from system.componentmodel.component
the "me." keyword appears. When it has no inheritance, "BeginInit" and
"EndInit" calls apears alone, with no object.

P.P.S : Sorry by my bad english and thanks a lot for help !

Some pieces of the code :

<TypeConverter(GetType(conversorMapeamento))> _
Public Class Mapeamento
   Inherits System.ComponentModel.Component
   Implements ISupportInitialize

....

  Public Sub BeginInit() Implements
System.ComponentModel.ISupportInitialize.BeginInit
       ...
   End Sub

   Public Sub EndInit() Implements
System.ComponentModel.ISupportInitialize.EndInit
         ...
   End Sub
End Class

<TypeConverter(GetType(conversor)),
DesignerSerializer(GetType(MeuSerializer), GetType(CodeDomSerializer))> _
Public Class UmaTabela
   Inherits System.ComponentModel.Component

...

<DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
   Public Property TabelaOrigem() As IListSource
       Get
           Return (tb)
       End Get
       Set(ByVal Value As IListSource)
           tb = Value
           Mapeamento.TabelaOrigem = tb
       End Set
   End Property

   <Editor(GetType(EditorMapeamento), GetType(UITypeEditor)),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
   Public Property Mapeamento() As Mapeamento
       Get
           Return (map)
       End Get
       Set(ByVal Value As Mapeamento)
           map = Value
       End Set
   End Property
End Class

Public Class MeuSerializer
   Inherits System.ComponentModel.Design.Serialization.CodeDomSerializer

   Public Overrides Function Deserialize(ByVal manager As
System.ComponentModel.Design.Serialization.IDesignerSerializationManager,
ByVal codeObject As Object) As Object

   End Function

   Public Overrides Function Serialize(ByVal manager As
System.ComponentModel.Design.Serialization.IDesignerSerializationManager,
ByVal value As Object) As Object
       Dim cd As CodeDomSerializer
       Dim codeObject As CodeStatementCollection
       Dim targetObject As CodeExpression
       Dim inv As CodeMethodInvokeExpression
       Dim novaColecao As New CodeStatementCollection
       Dim cs As CodeStatement
       Dim o As Object

       If IsNothing(value) Then
           Exit Function
       End If

       cd = manager.GetSerializer(GetType(UmaTabela).BaseType,
GetType(CodeDomSerializer))
       o = cd.Serialize(manager, value)

       If TypeOf o Is CodeStatementCollection Then

           codeObject = o
       Else
           codeObject = New CodeStatementCollection
           If Not IsNothing(o) Then
               If TypeOf o Is CodeExpression Then
                   codeObject.Add(DirectCast(o, CodeExpression))
               Else
                   codeObject.Add(DirectCast(o, CodeStatement))
               End If
           End If
       End If

       targetObject = MyBase.SerializeToReferenceExpression(manager,
DirectCast(value, UmaTabela).Mapeamento)

       inv = New CodeMethodInvokeExpression(targetObject, "BeginInit")

       novaColecao.Add(inv)

       Dim i As Integer
       For i = 0 To codeObject.Count - 1
           novaColecao.Add(codeObject(i))
       Next

       novaColecao.Add(New CodeMethodInvokeExpression(targetObject,
"EndInit"))
       Return (novaColecao)

   End Function
End Class
DRaiko - 21 Jul 2004 09:27 GMT
Hi Dennes,

The ISupportInitialize is (as far, as i see) recognized only when
implemented by components.

Wouldn't it be easyer (to solve the problem) to implement
the interface in the component that owns the collection, call
in EndInit() a method implemented in the collection, that iterates
through all members calling their initialization methods.

Another possibility is to override OnInsert() and OnSet() methods
of the collection itself initializing each member in the moment
when it adds.

The differences between these two approaches are obvious:

(i) when called in OnInsert/OnSet, initializing code will run
not only for deserialized members, but for all ones (== including
new members as they add in design mode and at runtime);

(ii) When initializing from EndInit() you can collect and prepare all
parameters you need. In OnInsert/OnSet methods you can access only
the new member and variables defined in the collection (and all
static fields of any class, of course). So, all values/pointers
you need must be passed to the collection (before the first member
adds) and saved there.
Usually it is enough to have a pointer to the owner control to get
all information the member initializer needs, but it depends.

Be aware: properties deserialization in InitializeComponent() is
ordered alphabelically. At the moment when members are deserialized and
add to collection, not all other properties are already set.

(iii) Initialization in in OnInsert/OnSet is done before the next
meber adds; Initialization called from EndInit is done when the whole
collection is already there. Look, what is better in your situation.

Regards,
Dima.

> Hi !
> I created a new component for my project. One of the properties of this
[quoted text clipped - 152 lines]
>     End Function
> End Class

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.