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 / September 2005

Tip: Looking for answers? Try searching our database.

Deserializing a VB file into IDesignerHost

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
David Whitchurch-Bennett - 22 Sep 2005 20:31 GMT
More than one way to skin a cat....

Still on the subject of the BasicDesignerLoader class......

I have written a forms designer, implementing IDesigner etc., and this works
very well. I am having trouble implementing the BasicDesignerLoader though..

The PerformFlush sub will successfully write the controls to a file using a
CodeDOMSerializer and the VBCodeProvider class. The file does indeed contain
all the information I want it to - horray!

The problem is getting it back again. I cannot see any methods to read the
file and convert the VB back into the CodeStatementCollection on the CodeDOM
object. I am sure the methods would also be same for CS as well.

So then, how do I convert the VB code from a text file back into the
IDesignerHost, in other words load the layout from a VB file?

Thanks,

David
"Jeffrey Tan[MSFT]" - 23 Sep 2005 09:52 GMT
Hi David,

Thanks for your post.

In your another post "XML Serialization in the BasicDesignerLoader Class",
I have provided you a Microsoft sample DesignerHost. In this sample, it
provided 3 ways to serialize the entire form designer: C# code file, VB.net
code file and Xml code file. However, it only provide the implementation to
deserialize Xml code file.

But, deserializing C#/VB.net code file is always the same way as the
serialization code. Please see the code snippet below:

// Autogenerates member declaration and InitializeComponent()
// in a new CodeTypeDeclaration
//
RootDesignerSerializerAttribute a =
TypeDescriptor.GetAttributes(root)[typeof(RootDesignerSerializerAttribute)]
as RootDesignerSerializerAttribute;
Type t = host.GetType(a.SerializerTypeName);
CodeDomSerializer cds = Activator.CreateInstance(t) as CodeDomSerializer;
IDesignerSerializationManager manager =
host.GetService(typeof(IDesignerSerializationManager)) as
IDesignerSerializationManager;
CodeTypeDeclaration td = cds.Serialize(manager, root) as
CodeTypeDeclaration;

It actually use reflection to get the CodeDomSerializer associated with the
component/control, then invoke CodeDomSerializer.Serialize to serilize the
control. We should do the reverse work, just get the CodeDomSerializer and
invoke its Deserialize() method to get object instance back.

Hope this helps

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Signature

Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

David Whitchurch-Bennett - 23 Sep 2005 11:31 GMT
Hi Jerrrey,

Thanks for the reply. I already have the serialize working great, and here
is the code that I am using (in VB I am afraid!)

Protected Overrides Sub PerformFlush(ByVal serializationManager As
System.ComponentModel.Design.Serialization.IDesignerSerializationManager)
       ' create Code Document Object Model Serializer to get code statements
       Dim codeDOM As CodeDomSerializer =
serializationManager.GetSerializer(GetType(IDesignerHost),
GetType(CodeDomSerializer))
       ' get code statement collection from the serializer
       Dim codeStatementCollection As CodeStatementCollection =
codeDOM.Serialize(serializationManager, _host.RootComponent)
       csc = codeStatementCollection
       ' create vb provider to translate statements into VB text
       Dim vbProvider As Microsoft.VisualBasic.VBCodeProvider = New
Microsoft.VisualBasic.VBCodeProvider
       ' test writer
       Dim writer As New System.IO.StreamWriter("C:\Test.txt")
       writer.AutoFlush = True
       ' loop through each statement, and write to the text writer
       For Each s As CodeDom.CodeStatement In codeStatementCollection
           vbProvider.GenerateCodeFromStatement(s, writer, New
System.CodeDom.Compiler.CodeGeneratorOptions)
       Next
       writer.Close()
   End Sub

When trying to deserialize, I have the following code so far.

Protected Overrides Sub PerformLoad(ByVal serializationManager As
System.ComponentModel.Design.Serialization.IDesignerSerializationManager)
       ' read the VB text file
       Dim reader As New System.IO.StreamReader("C:\Test.txt")
       ' somehow get VB code back into CodeStaementCollection
       Dim codeStatementCollection As CodeStatementCollection
       ' create Code Document Object Model DeSerializer
       Dim codeDOM As CodeDomSerializer =
serializationManager.GetSerializer(GetType(IDesignerHost),
GetType(CodeDomSerializer))
       ' deserialize into the root component object
       Dim formObject As Form = codeDOM.Deserialize(serializationManager,
codeStatementCollection)
       ' somehow get the form object into the DesignerHost

I have two problems here.

Firstly, _host.RootComponent is read-only (_host is the DesignerHost), so
how to I get my deserialized form back into this. (I will read the other
sample you suggested as well)

Secondly and more importantly, I can't translate the VB text file back into
CodeDom statements. I have searched for how to do this, but cannot find any
information. There must be a way as the VB.NET designers do it all the time.

I hope this all makes sense, and I have probably missed something very
obvious! Hopefully you can help me out here!

David.
David Whitchurch-Bennett - 23 Sep 2005 15:29 GMT
Hi Jeffrey,

Well, I have been working on this all day so far, and I've got a little
further. As mentioned in the above post, I can deserialize no problem. I have
also added code to serialize the CodeDOM statement collection to a binary
file, rather than to VB code. This is great, and it works OK.

I can also deserialize the binary file back to CodeDOM statemements, and I
have tested this by writing them back to VB code, and it looks fine, so I can
read and write the CodeDOM statement collection - this is great.

The final thing is can't seem to get working is these two lines...

' create Code Document Object Model DeSerializer
       Dim codeDOM As CodeDomSerializer =
serializationManager.GetSerializer(GetType(IDesignerHost),
GetType(CodeDomSerializer))
       ' deserialize into the root component object
       codeDOM.Deserialize(serializationManager, codeStatementCollection)

I am sure something is missing (the deserialize function should return an
object, and I need to add it to the designer I guess), BUT it won't create
that object, which should be a form. Instead, it throws the following
exception, which I can't understand as the Form type is definately referenced
in the project.

System.ComponentModel.Design.Serialization.CodeDomSerializerException was
unhandled by user code
 HelpLink="SerializerTypeNotFound"
 Message="Could not find type 'System.Windows.Forms.Form'.  Please make
sure that the assembly that contains this type is referenced.  If this type
is a part of your development project, make sure that the project has been
successfully built."
 Source="System.Design"
 StackTrace:
      at
System.ComponentModel.Design.Serialization.CodeDomSerializerBase.Error(IDesignerSerializationManager manager, String exceptionText, String helpLink)

      at
System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager
manager, String name, CodeExpression expression)

      at
System.ComponentModel.Design.Serialization.CodeDomSerializer.DeserializeStatementToInstance(IDesignerSerializationManager manager, CodeStatement statement)

      at
System.ComponentModel.Design.Serialization.CodeDomSerializer.Deserialize(IDesignerSerializationManager manager, Object codeObject)

      at
IndexCardDesigner.DesignerLoader.PerformLoad(IDesignerSerializationManager
serializationManager) in O:\Visual Studio Projects\Docstore.NET\Index Card
Designer\IndexCardDesigner\DesignerHost\DesignerLoaderService.vb:line 211

      at
System.ComponentModel.Design.Serialization.BasicDesignerLoader.BeginLoad(IDesignerLoaderHost host)

> Hi David,
>
[quoted text clipped - 35 lines]
> Get Secure! - www.microsoft.com/security
> This posting is provided "as is" with no warranties and confers no rights.
"Jeffrey Tan[MSFT]" - 26 Sep 2005 07:38 GMT
Hi David,

Thanks for your feedback.

Because I did not have your source code and without reproduce your problem,
I can not give very useful hint to this exception. Also, in the exception
call stack, I do not know what does these symbols mean:
CodeDomSerializerBase
CodeDomSerializer.DeserializeStatementToInstance

Normally, these are not .Net BCL classes/methods(I can not see these
symbols in reflector).

Based on my research in the with Reflector, VS.net IDE already implemented
several CodeDomSerializer for us, such as RootCodeDomSerializer,
ControlCodeDomSerializer, ComponentCodeDomSerializer etc..

Usually, we invoked RootCodeDomSerializer.Deserialize method first, then it
internally invoke loop through the parameter collection we passed to it and
invoke corresponding child
ControlCodeDomSerializer/ComponentCodeDomSerializer for us. So the entire
Code dom is parsed and added to the designer by it.

RootCodeDomSerializer.Deserialize requires we pass CodeTypeReference type
for the second parameter. So I think we should manually use CodeDom classes
to parse the C#/VB.net code file into CodeTypeReference, then pass this
CodeTypeReference to the RootCodeDomSerializer.Deserialize.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Signature

Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.


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.