Dirkster99 / AvalonDock

Our own development branch of the well known WPF document docking library
Microsoft Public License
1.39k stars 319 forks source link

After changing the style (theme), when you pin a side bar it will disappear #402

Closed mladdaga closed 1 year ago

mladdaga commented 1 year ago

After hours of research I found that in LayoutAnchorSideControl, in the LayoutAnchorSideControl_Unloaded method, for some reason, it's removed the collectionChanged handler on the model's children _model.Children.CollectionChanged -= OnModelChildrenCollectionChanged; Removing this line from the code everything works fine. It seems that is the root of a lot of other Issues opened around the load of a different theme.

It's easy to reproduce on the MVVMTestApp

image

image

image

image

Wenveo commented 1 year ago

Hi mladdaga. Like you said, change the style (theme) and pin a side bar it will disappear. This is due to the parent's template change, And the child control is disconnected (The Unloaded event handler will be raised).

ApplyNewTemplate (Change the template) -> Unloaded (The event handlers will be removed) -> Loaded (Reconnect, but we don't have the Loaded event handler) https://github.com/Dirkster99/AvalonDock/blob/1d4d30d9969236c3717b8a6f430809a230ff671a/source/Components/AvalonDock/Controls/LayoutAnchorSideControl.cs#L145-L149

Wenveo commented 1 year ago

Fortunately, we can add a Loaded event handler in OnApplyTemplate. So that we can add back the OnModelChildrenCollectionChanged event handler on apply the new template.

// LayoutAnchorSideControl.cs

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    Loaded += LayoutAnchorSideControl_Loaded;
}

private void LayoutAnchorSideControl_Loaded(object sender, RoutedEventArgs e)
{
    Loaded -= LayoutAnchorSideControl_Loaded;
    Unloaded += LayoutAnchorSideControl_Unloaded;
    _model.Children.CollectionChanged += OnModelChildrenCollectionChanged;
}

private void LayoutAnchorSideControl_Unloaded(object sender, RoutedEventArgs e)
{
    _model.Children.CollectionChanged -= OnModelChildrenCollectionChanged;
    Unloaded -= LayoutAnchorSideControl_Unloaded;
}

image image

It will work.