I am trying to save the MDI state when closing the application and load it when opening. Like FireFox, it opens all the web pages last time when you close the application. I've noticed that UltraTabbedMdiManager have methods like SaveAsXml and LoadFromXml.What is contained in the saved XML file?
What do I need to do if I want to open the last visited pages like FireFox? Thanks.Mike
The XML file will contain all properties and values which are publicly exposed in the tabbed mdi manager. It is intended to save customizations the user might have made, through both the default UI, as well as any additional UI you have added to your application to give the user control over certain aspects of the tabbed mdi manager. One of the reasons to save and load this file would be to maintain the tab groups into which the user has organized the mdi child forms. However, loading the XML file will not open the forms which were previously opened. You must keep track of which forms were open when the XML file was saved and re-open them before loading the XML file.
>You must keep track of which forms were open when the XML file was saved and re-open them before loading the XML file.
So i guess i should save the open forms into a separate file, instead of messing this XML file.
In fact, all I want to save for each form is the file name to initialize it. Is it possible to tag objects (e.g., the list of file names in this case) to the UltraTabbedMdiManager? Is it worth doing that?
>to maintain the tab groups into which the user has organized the mdi child formsThe only think i can think of is to switch between normal MDI and tabbed MDI. Anything else user acn do to organize child forms?Thanks!
mike2008 said:In fact, all I want to save for each form is the file name to initialize it. Is it possible to tag objects (e.g., the list of file names in this case) to the UltraTabbedMdiManager? Is it worth doing that?
No, because the load operation would load in the tag values and try to find the mdi child forms all before returning. There would be no way to intervene after the tag values were loaded to open the forms before the load operation attempted to find them. I would recommend using a separate file for this.
mike2008 said:>to maintain the tab groups into which the user has organized the mdi child formsThe only think i can think of is to switch between normal MDI and tabbed MDI. Anything else user acn do to organize child forms?
Just like in VS, the user can drag the tabs down or to the side to form new tab groups. They can also form new tab groups by right-clicking the tab and selecting 'New Horizontal Tab Group' or 'New Vertical Tab Group'
It looks like OptionField in Serializable class does not work when using SOAP formatter.http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=140592
I implemented ISerializable interface for the class, and added my own serialization and deserialization method to handle optional fields.It works fine now. Thanks.
I am not sure what the problem is from the stack trace. It could be a problem with the application or the tabbed mdi manager. I would recommend submitting a sample and the old layout file to the support group so it can be investigated further: http://es.infragistics.com/gethelp.
Mike Dour"]In the handler, you can get the PersistedInfo for the tab and create a Form (or use an existing Form) to use for the tab. Set the Form on the Form property of the event arguments.
I successfully save the xml and load when opening.
Now I need to add more information to the PersistedInfo object, e.g., some state information of the child form. I have a Serializable class called MdiChildFormState to save to PersistedInfo, and I added the new members with [OptionalField()] attribute.
Then I tried to load the old version of the MDI layout file (without new memebers), and I got the following exception: [System.ArgumentNullException] {"Member at position 1 was null.\r\nParameter name: members"} System.ArgumentNullException
and ex.StackTraceis like the follows: at System.Runtime.Serialization.FormatterServices.PopulateObjectMembers(Object obj, MemberInfo[ members, Object[ data) at System.Runtime.Serialization.Formatters.Soap.ReadObjectInfo.PopulateObjectMembers() at System.Runtime.Serialization.Formatters.Soap.ObjectReader.ParseObjectEnd(ParseRecord pr) at System.Runtime.Serialization.Formatters.Soap.ObjectReader.Parse(ParseRecord pr) at System.Runtime.Serialization.Formatters.Soap.SoapHandler.EndElement(String prefix, String name, String urn) at System.Runtime.Serialization.Formatters.Soap.SoapParser.ParseXml() at System.Runtime.Serialization.Formatters.Soap.SoapParser.Run() at System.Runtime.Serialization.Formatters.Soap.ObjectReader.Deserialize(HeaderHandler handler, ISerParser serParser) at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream serializationStream, HeaderHandler handler) at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream serializationStream) at Infragistics.Win.UltraWinTabbedMdi.UltraTabbedMdiManager.Load(Stream stream, Boolean xml) at Infragistics.Win.UltraWinTabbedMdi.UltraTabbedMdiManager.LoadFromXml(Stream stream)
Any idea how I can solve this issue?Thanks.
Mike2008
vrn said:I am guessing because ReadBase64 is reading the next node and decoding it, the order of loading the controls is important? So it should be read in the same sequence that I saved it?
Yes, that is correct.
vrn said:Do you have suggestion on how I can make the loading sequence independent of the saving sequence? This can prove useful for my design where I am trying to make each component completely independent of the other. So each component should be able to figure out its own setting from the larger XML file.
Instead of using an XmlTextReader, you can try to implement something using an XmlDocument. Then each control can iterate the child nodes of the document and find the node with their stream name and just read in that node. Alternatively, you could keep the same approach and read in all streams and populate them into a Dictionary<string,Stream>, where the key is the stream name. Then when each control goes to load, they just access the dictionary with the name they are looking for.
Mike Dour"] My code snippet used an XmlTextReader, which just reads the nodes in order, so it did not need to specify the config file it was looking for. I could have put asserts before loading each stream to make sure the current node had the expected names before loading them.
My code snippet used an XmlTextReader, which just reads the nodes in order, so it did not need to specify the config file it was looking for. I could have put asserts before loading each stream to make sure the current node had the expected names before loading them.
Mike your code worked like a charm!
- I am guessing because ReadBase64 is reading the next node and decoding it, the order of loading the controls is important? So it should be read in the same sequence that I saved it?
- Do you have suggestion on how I can make the loading sequence independent of the saving sequence? This can prove useful for my design where I am trying to make each component completely independent of the other. So each component should be able to figure out its own setting from the larger XML file.