[Version 2.0] Show hidden LayoutAnchorable after previous container has been removed.

Mar 13, 2012 at 10:28 PM
Edited Mar 13, 2012 at 10:57 PM

Firstly I'd like to say great work on the new version.

I have a docking manager with 1 document and 2 anchorables, 1 anchorable is anchored to the left side of the main document pane, the other is in a floating window.

At this point I can hide and show either of the anchorable windows with any problem. However if I hide the first anchorable and then drag the second anchorable into the main document pane, I can not longer show the first (hidden) anchorable. At this point in the Show() method of LayoutAnchorable (below) the PreviousContainer property is null.

 

public void Show()
{
    if (!IsHidden)
        return;

    RaisePropertyChanging("IsHidden");
    if (PreviousContainer != null)
    {
        var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup;
        previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this);
        IsSelected = true;
        IsActive = true;
    }
    RaisePropertyChanged("IsHidden");
}

I think that the AnchorablePane is removed by the CollectGarbage method on the LayoutRoot. Maybe this should not get removed if it is being referenced by a hidden element. Something like ...

public void CollectGarbage()
{
    // ... some code
    
    foreach (var contentReferencingEmptyPane in this.Descendents().OfType<LayoutContent>()
        .Where(c => c.PreviousContainer == emptyPane && c.FindParent<LayoutFloatingWindow>() == null))
    {
        if ((contentReferencingEmptyPane is LayoutAnchorable) && ((LayoutAnchorable)contentReferencingEmptyPane).IsHidden)
            continue;

        contentReferencingEmptyPane.PreviousContainer = null;
        contentReferencingEmptyPane.PreviousContainerIndex = -1;
    }

    // ... some code
}

Although there maybe a better solution.

Mar 15, 2012 at 5:48 PM

Hi,
thanks for the hint. Your fix works and I've added to latest sources.
Anyway I think that there are circumstances when the show method have the only option to create a pane on the fly and put itself there.
Ado

Mar 15, 2012 at 5:57 PM

Your welcome,

I did think about that as well, currently in my test application when I create a new window which has no previous container, I will add it to the main document pane. I know in your previous versions, when you call the show method you could give a dock position and a relative, but with the new layout structure that isn't as easy, or even necessary.

I do however think it would be useful to provide a show method that would create a new LayoutAnchorable in a floating window, I don't currently see a way to do that, please correct me if I'm wrong.

FL

Mar 21, 2012 at 4:20 PM

Ado,

I've found a another bug, that is related to my fix. If you have a LayoutAnchorable in a floating window, you hide the LayoutAnchorable so the window is hidden, and save the layout. When you load the saved layout the floating window will be visible and empty, as the ComputeVisibility method is not called when loading the layout.

Here is a fix in the DockingManager.OnLayoutChanged method:

protected virtual void OnLayoutChanged(LayoutRoot oldLayout, LayoutRoot newLayout)
{
    // ... some code

    foreach (var fw in Layout.FloatingWindows)
    {
        _fwList.Add(GetUIElementForModel(fw) as LayoutFloatingWindowControl);
        ((ILayoutElementWithVisibility)fw).ComputeVisibility();
    }

    // ... some code
}

Again, there might be a better way to do this, so please review.

Cheers,

FL

May 7, 2015 at 10:22 AM
Edited May 7, 2015 at 10:26 AM
Hi FallLine,

I have found another issue:
If you float any docked anchorable and then Close the floating window and then Reopen it again and then if you try to dock it, it wont go to previous docked position. It just doesn't have the previous container. It randomly gets docked to any other ancorable pane.

Actually, when you float the docked pane, the docked pane becomes the previous container. Then you close the floating window, the previous container gets changed to the floating window pane. Now if you reopen the floating window again, the previous container gets changes to null.

Any idea how this can be fixed in the code? Do we need to add additional properties to handle the previous container trail for both floating and docked anchorables??

Cheers,
AMB1000
May 7, 2015 at 6:32 PM
Hi AMB1000,

I haven't had a chance to test this out yet, but I'll try to get to it later today. You might be right that having a previous floating container property and a previous anchorable container property would be enough. Alternatively a limited history of previous containers might be more extensible, so when attempting to re-open/dock a it could say have a list of previous container ids, limited to say 5 (just a random number, but should be enough or could be configured) the docking code could check the previous container ids in reverse order to find any that are still alive.

This is just off the top of my head at the moment, but I will try to play around with it later.

Also, I'm not sure how active this codeplex site is, now that AvalonDock is part of the Xceed WPF Toolkit might need to make the change there to get a release.

Cheers,
FL