QA: Delayed layout restore for some panels
See original GitHub issueHi,
im using Load/Save layoud similar way you describe it on CodeProject. Catching LayoutSerializationCallback event and trying to find coresponding viewModel for LayoutItem
private void LayoutSerializer_LayoutSerializationCallback(object sender, LayoutSerializationCallbackEventArgs e)
{
// This can happen if the previous session was loading a file
// but was unable to initialize the view ...
if (string.IsNullOrWhiteSpace(e.Model.ContentId) || (e.Content = ReloadItem(e.Model)) == null)
{
e.Cancel = true;
return;
}
}
private object ReloadItem(object item)
{
object ret = null;
switch (item)
{
case LayoutAnchorable anchorable:
//list of tools windows
ret = Manager.Tools.FirstOrDefault(i => i.ContentId == anchorable.ContentId);
if(ret == null && anchorable.ContentId.StartsWith(MapPanel.MapPanelPrefix))
{
MapPanels.Add(anchorable);
}
break;
case LayoutDocument document:
// list of restored documents
ret = Manager.Documents.FirstOrDefault(i => i.ContentId == document.ContentId);
break;
default:
throw new NotImplementedException("Not implemented type of AD item ");
}
return ret;
}
This works fine, when i have all ViewModels available when deserializing/restoring layout.
But im thinking about something like delayed layout restore. In my case i have some documents and some panels available at start. But there can be some panels (call them MapPanel) that are loaded later (viewModels are loaded somewhere in future). And i cant figure out, how to restore layout for these panels.
For this case i have List<LayoutAnchorable> MapPanels to store anchorables that are loaded at avalondock layout load and trying to restore them in BeforeInsertAnchorable in ILayoutUpdateStrategy. But when i debug it, stored LayoutAnchorable has different parent that stored one. So i assume that after canceling (e.Cancel = true) in LayoutSerializationCallback somehow modifies not restored anchorable.
public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer)
{
if (anchorableToShow.Content is ToolPanel tool)
{
if(tool is MapPanel)
{
anchorableToShow = LayoutSaveLoadUtil.Instance.MapPanels.FirstOrDefault(mp => mp.ContentId == anchorableToShow.ContentId);
}
var destPane = destinationContainer as LayoutAnchorablePane;
if (destinationContainer != null && destinationContainer.FindParent<LayoutFloatingWindow>() != null)
return false;
var dockLeftPane = layout.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault(d => d.Name == tool.PreferredLocation + "Pane");
if (dockLeftPane != null)
{
dockLeftPane.Children.Add(anchorableToShow);
return true;
}
return false;
}
return false;
}
So im curious what is right approach to achieve this. I was also thinking about restoring layout (again) after MapPanel is loaded, but i dont know how to skip all other LayoutItems. So is there any posibility how to restore single Anchorable position, floating parent, docking, size etc…?
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
Hi,
there is no way restore only a single Anchorable as far as AvalonDock is concerned. But you could do this if you do the restore in more than 1 stage:
Stage 1: restore layouts with controls as usual (but don’t load content for each control, yet) Stage 2: load content for for each control (via background thread) only if control is visible and load active control first
This approach would be smoother but is harder to implement as it needs a lot of task coordination by the application framework. Everyone has his own preferences for it, some use Thread class instances, others use other technologies, such as, Rx.
Its definetly an advanced topic outside of AvalonDock’s scope and you should test your concept on a small (1 document) test app before trying it with AvalonDock, because you might otherwise get async errors left and right and won’t get anywhere useful when trying it with AvalonDock right away … 😦
I have added my version of delayed layout loading in MLibTest by loading the content when the usercontrol view is loaded. This will delay all documents that are not currently visible since tabbed items are virtualized by default. You could obviously do something similar with LayoutAnchorables.
Also worth a note:
MainWindow
is shown to make app appear to start quickly and enableMainWindow
to show progress and/or possible error messages (but I would put errors into an Output toolwindow)Please let me know what you think about it - see any bugs or ‘obvious’ points of improvement?