Hello. I have 2 questions.
I'm using a xamoutlook bar. One of the outlookbar groups has the dock manager. The others have different content. So when they click on a different outlookbar group the content gets swapped out.
<ContentControl Content="{Binding CurrentViewModel}" Grid.Row="1" Grid.Column="1"/>
So say someone rearranges the all the panes in the dockmanager then clicks on a different outlookbar group then clicks back to the one with the dock manager. The layout resets to what is defined statically in the xaml. In order to remember what the layout was I'm assuming that I will have to save the layout every time a bar group other then the one with the dock manager gets click to remember how the user left the layout. Is this correct or is there some other way of doing this without saving to a file? I'm asking cause I'm not closing the application just swapping the content in ContentControl.
Second question.
When I save a layout I need to get a handle of the DockManager. How can I do this if I'm using the mvvm pattern? Would I somehow bind to the DockManager like binding to properties? I could do it in a code behind since I can directly reference the DockManager. So a button click would trigger an event which would trigger the saveLayout method but then I'm breaking the mvvm pattern.
Thanks
Hi Kris,
This is the expected behavior. When you swap out the content like that, the old UI elements are thrown out. When you bring the dockmanager back, it recreates all the elements again which is why it appears to lose its updated layout. At the moment I'm not sure of the best way to handle this in an MVVM friendly way, I'm currently looking into this. But SaveLayout and LoadLayout are going to be necessary in maintaining the layout. I'll update you once I've found a good way to do this with MVVM.
Hello Kris,
Please see the attached sample. I created a behavior that will restore the layout of the dockmanager when it is constantly Loaded/Unloaded. It makes use of a view model property in order to retain the layout xml so in order for this to work you'll need to create a string property in your dockmanager view model and then bind it to the behavior's Layout property.
Let me know if you have any questions.
Thanks for taking the time. I noticed that the code only remembers if pane 3/4 is pinned but pane 1 or 2.
Sorry about that. I was handling the pane's Unloaded event to unhook some events and didn't realize they would be called when you unpin them. This caused their pin states to no longer be saved. I have changed how I handle the events so it should work now.
Thanks for the update. I'm running into another problem. I have 3 panes. Each user has a home pane that I want to have pinned and the other 2 unpinned based on whatever the home pane is of the user. This is determined by a database call. So I bind the IsPinned property of the split panes to a property in the view model:
IsPinned="{Binding IsPinnedPane1}"
IsPinned="{Binding IsPinnedPane2}"
IsPinned="{Binding IsPinnedPane3}"
In the view model constructor I set the IsPinnedPane1/2/3 properties to either true or false based on what the users home pane should be. I noticed that when I bind the IsPinned property and then switch the <ContentControl Content="{Binding CurrentViewModel}" /> to something else if a user makes a different outlook bar selection I get an exception in the RestoreDockManagerlayout.cs :
private void SaveLayout() { if (!_isLoading) { // this saves the layout to the viewmodel so it can be restored later _saving = true; Layout = AssociatedObject.SaveLayout(); <- THE EXCEPTION HAPPENS HERE _saving = false; } }
InvalidOperationException -> "Cannot modify the logical children for this node at this time because a tree walk is in progress."
You are binding to the ContentPane's IsPinned property? If so, then why are we saving the dockmanager layout when the user pins/unpins a pane? You can just set a TwoWay binding to properties in your view model and use that to store the state of the pane. When your dockmanager template comes back the bindings will be reapplied and the contentpanes will use whatever pinned state was saved in the view model. You can get rid of all that code I added for keeping track of the pane's IsPinned property and raising events for it.
The way I would like it to work is like so -> When the user starts up the application the initial pane that should be pinned is their home pane. Now as they start using the application they may pin/unpin/move the content panes around. Then they might click on the different XamOutlookBarGroup and then click back on the one with the DockManager. The dock manager should remember the changed layout. They close the application and open it back up, their home pane should be pinned while the other ones should not.
Your suggestion of removing the pinning code from the RestoreDockManagerLayout class and setting the Mode=TwoWay in the binding properties has it working exactly as I want it to. Thank very much for the suggestion.