In a MDI application I have a number of docked controls that are serialized when the form closes. At this moment dockManager.SaveDockState() is invoked.
When I load the form, I deserialize the controls (the docking manager is deserialized automatically) and then I do something like:
foreach (Control c in frm.controls)
This works fine.
I do now the serialization without closing the form, and I serialize the docking manager using the dockManager.SaveDockState(params).
I close all the controls and then I load what I saved, manually restoring the manager as well.
I use exactly the same approach as above (DockControl..), but in this case the manager displays the controls twice: once without any data and once with the saved data.
Am I doing something wrong?
I can send you a small example, if that helps.
PSPrakash S Syncfusion Team January 24, 2003 03:43 PM
It is not necessary to call the DockingManager.DockControl() method on controls a second time if they have already been displayed once and then just hidden through the DockingManager.SetDockVisibility(FALSE) method. The DockControl() or the SetEnableDocking() methods have to be called only when the host form is Closed/Disposed, or if the controls are explicitly removed from the DockingManager through the SetEnableDocking(Control, FALSE) method.
Just invoke the LoadDockState() method without the DockControl()/SetEnableDocking() calls when you want to load a new state for the existing but hidden controls. If this doesn't take care of the problem, send me the sample and I will take a look at it.
BVBruno VaisJanuary 29, 2003 02:44 PM
I attached an example. To reproduce my problem do the following:
- start the app
- change the text in the control
- save it (Ctrl + S)
- close the app
- start the app again
- close the control
- load (Ctrl + L)
Without a call to ..EnableDocking, the manager will display a control without the saved info.
With a call though, it displays to controls.
PSPrakash S Syncfusion Team January 31, 2003 11:02 AM
I just took a look at the sample, and the LoadDockState/SaveDockState methods work as intended ie., the docking states are correctly saved and restored. The catch here is that before you call LoadDockState(), the dockable controls themselves should all be enabled for docking. If the persisted state has docking information for a set of controls, and during the load, any one particular control has not been enabled for docking, then the dock information for the particular control(s) will be ignored. This is the behavior that you are observing with the 'thePlugin1' window. It is incorrect to call SetEnableDocking(thePlugin1) after the LoadDockState() command. Modify your implementation such that all controls are created and enabled for docking during application startup itself, and then invoke LoadDockState() from within the menu command handler.
BVBruno VaisFebruary 4, 2003 02:16 PM
Am I supposed to enable a control for docking using something else than SetEnableDocking?
Assuming the answer is no, I tried the following:
- in OnLoad I de-serialize the control
- enable it for docking (call to SetEnable..)
- load the docking info (call to LoadDockState..)
and it doesn't work. What am I missing?
PSPrakash S Syncfusion Team February 5, 2003 06:01 PM
Docking can be enabled for a Control by using one of the following methods - SetEnableDocking(), DockControl() or FloatControl(). While SetEnableDocking() will position the control at the default left border of the Form, the other 2 methods allow the dock/float position to be specfied.
A couple of things to be looked into here:
1. You will need to invoke the SetEnableDocking/DockControl methods only for those controls that have not already been enabled as dockable windows through the designer.
2. More importantly, the Form.Load event is not a good place to customize the docking layout. You will have to do this from a handler for the DockingManager.NewDockStateEndLoad event. Please refer to the following the Essential Tools knowledgebase link - http://www.syncfusion.com/KB/Tools/Tools_c35c.asp#q564q.
Bear in mind that when invoking the DockingManger.LoadDockState() method from within the NewDockStateEndLoad handler it is necessary to maintain some kind of a flat to prevent recursion.
I hope this helps. If not, please let me know.
BVBruno VaisFebruary 7, 2003 02:12 PM
Here's what I'm trying to do:
- save the contents and the docking info of the control, and load it after I close the control or the application
How do I do that?
I don't see how the NewDockStateEndLoad can help me with that?
Can you send me an example, maybe?
PSPrakash S Syncfusion Team February 10, 2003 09:31 AM
The DockingManager's initialization routine upon application startup begins from the Form.Load event and the DockingManager.NewDockStateEndLoad event is fired when the initialization is complete. Hence if you want to load a custom serialized state (ie., a state that you have persisted yourself and that which is not tied to the default serialization support provided by the framework itself), then this state will have to be loaded from a handler for the NewDockStateEndLoad event using a flag to prevent recursion. You need to do this only if this custom state is to be loaded upon application startup. However, if you want to load your custom state in response to a menu(or other) command event, then you can directly invoke the DockingManager.LoadDockState() method with the persistence information.
I have attached a sample that has a few docking windows and 2 buttons, the first of which saves the current docking state and the second loads the persisted state. Both saving to the default IsolatedStorage as well as writing to a custom XML file are shown. Please refer to the method handlers for details.
I hope this helps. Please let me know if you have any questions about the implementation.
BVBruno VaisFebruary 10, 2003 12:16 PM
Thanks for the example, but it doesn't solve my problem. It shows how to save the docking state, but it doesn't show how to save the contents (what's inside the docked windows).
Going back to my attachement (SaveStates.zip - I used a text box, easier to save), here are the problems:
1. First I thought that the docking manager takes care of serializing the contents of the control, therefore I did not add any serialization for the control
- with this approach, everything works fine if I don't close the application; the manager saves the contents (not to the disk, though; I looked in the XML file and there's no trace of the text I entered);
- if I close the application and start it again, the manager loads only the docking states
2. Then I realized that I should serialize the text myself (hence the GetObjectData functions)
- when I click "Save" I save the text to a file and the docking state to another file (by the way, why does the serializer overwrite instead of appending?)
- when I re-start the application, I deserialize the text (hence the constructors with SerializationInfo), and the docking information
- at this point I have 2 controls: one from the deserialization of the form (with accurate content) and one from the deserialization of the docking manager.
So, to summarize:
1. Where does the manager save the contents (if I don't close the application)?
2. Why does the serializer overwrite instead of appending (a call to SerializeIsolatedObject followed by one to SaveDockState rewrites the XML file)?
3. How do I sync the contents if I re-start the application?
pfeww.. long one ;-)
PSPrakash S Syncfusion Team February 10, 2003 05:02 PM
The DockingManager's serialization implementation is completely oblivious of it's client control's and uses only the 'Control.Name' property as a key while saving/loading the dockstate information. As you have already discovered, it is up to the application to provide the internal serialization routines of the controls.
The default storage medium for the DockingManager is the application's IsolatedStorage area and it is to this medium that the dockstate information is written to & read from when using the default DockingManager.PersistState property or the non-parametrized SaveDockState()/LoadDockState() methods. However, you can write out your custom dockstate information to a medium of your choice (XML/Binary file, Windows registry) by using the parameterized LoadDockState/SaveDockState overrides that were demonstrated in sample that I sent you earlier.
I think the problem here is that you are recreating your controls every time you load a new dockstate. The only time the controls need to be created is when the application first starts. Later on, closing the controls through the docking window's close ('X') button merely hides the control, and will redisplay it if the LoadDockState() is invoked with a previously persisted state during which the particular control was visible. Looks like you are creating the control during each invocation of LoadDockState() and that is why you are having multiple instances of the same control.
I hope this clarifies the situation. If not, then please let me know.