I am trying to learn the AvalonDock environment in WPF. I have an anchorable pane that contains a treeview which displays a list of objects (basically contains a name and value).
I also have some document panes that host a UserControl. I can drag an item from the treeview into a document (UserControl which is basically a WrapPanel) and then drop it, it adds a 2nd user control type (this user control has a textblock bound to 'name' and a textbox bound to 'value') to my control hosted by the document.
Now - I want to be able to save this layout- with the dynamic content created by the drag/drop.
Is this possible? When using the XmlLayoutSerializer I see the generated xaml has my documents and anchorables, but none of these items have any content.
Should I instead be saving a collection of the objects (i.e. the ObservableCollection I am bound to) and initialize the collection when I want to 'restore' the view?
The intent is to have a view that end-users can modify to display the data they want (from the treeview) and arrange the layout as they see fit.
Thanks for any pointers
There's an article on CodeProject which describes a solution: https://www.codeproject.com/articles/719143/avalondock-tutorial-part-load-save-layout
You may also take a look at the Gemini project, which has a much more flexible solution: https://github.com/tgjones/gemini/ The important stuff is in the Gemini/Framework directory.
It's a pure MVVM solution which keeps all the documents and layout items in the main/shell viewmodel and databinds to it. While saving layout, it asks every viewmodel to save its state and the DockingManager
state is persisted last. While loading layout, all the state is read first and the viewmodels are recreated in the LayoutSerializationCallback
event of the AvalonDocks XmlLayoutSerializer
. This is nice and clean approach, but (AFAIK) it cannot handle a situation when the controls are created purely in XAML and connected to the rest of the application using some kind of messaging (Prism EventAggregator
for example).
To solve this kind of problem, you'll need a help from the view which hosts DockingManager
, ask it for a list of LayoutAnchorables
and LayoutDocuments
and save/load their states using the similar mechanism. It's not as elegant and pure MVVM as the original solution, but I found it more flexible. You can wrap everything in a few interfaces and extension methods.
I did something like that for my project and it works great. Might put it on GitHub some day.