Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InvalidOperationException - "The control already has a visual parent." when opening a menu item on custom styles #5685

Closed
emmauss opened this issue Mar 19, 2021 · 4 comments
Assignees
Labels

Comments

@emmauss
Copy link
Contributor

emmauss commented Mar 19, 2021

Describe the bug
This issue occurs when a menu item with submenus is opened after a window has had a new style applied. It throws the following exception

System.InvalidOperationException: The control already has a visual parent.
   at Avalonia.Visual.ValidateVisualChild(IVisual c) in /_/src/Avalonia.Visuals/Visual.cs:line 554
   at Avalonia.Visual.<>c.<.ctor>b__16_0(IVisual visual) in /_/src/Avalonia.Visuals/Visual.cs:line 123
   at Avalonia.Collections.AvaloniaList`1.InsertRange(Int32 index, IEnumerable`1 items) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 387
   at Avalonia.Controls.Panel.ChildrenChanged(Object sender, NotifyCollectionChangedEventArgs e) in /_/src/Avalonia.Controls/Panel.cs:line 112
   at Avalonia.Collections.AvaloniaList`1.NotifyAdd(T item, Int32 index) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 680
   at Avalonia.Collections.AvaloniaList`1.Add(T item) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 205
   at Avalonia.Controls.Presenters.ItemVirtualizerNone.AddContainers(Int32 index, IEnumerable items) in /_/src/Avalonia.Controls/Presenters/ItemVirtualizerNone.cs:line 96
   at Avalonia.Controls.Presenters.ItemVirtualizerNone..ctor(ItemsPresenter owner) in /_/src/Avalonia.Controls/Presenters/ItemVirtualizerNone.cs:line 21
   at Avalonia.Controls.Presenters.ItemVirtualizer.Create(ItemsPresenter owner) in /_/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs:line 203
   at Avalonia.Controls.Presenters.ItemsPresenter.PanelCreated(IPanel panel) in /_/src/Avalonia.Controls/Presenters/ItemsPresenter.cs:line 151
   at Avalonia.Controls.Presenters.ItemsPresenterBase.CreatePanel() in /_/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs:line 231
   at Avalonia.Controls.Presenters.ItemsPresenterBase.ApplyTemplate() in /_/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs:line 137
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 554
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Controls.Presenters.ScrollContentPresenter.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs:line 256
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Controls.DockPanel.MeasureOverride(Size constraint) in /_/src/Avalonia.Controls/DockPanel.cs:line 112
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.Layoutable.MeasureOverride(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 625
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 40
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding, Thickness borderThickness) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 33
   at Avalonia.Controls.Border.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Border.cs:line 121
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 40
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding, Thickness borderThickness) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 33
   at Avalonia.Controls.Presenters.ContentPresenter.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Presenters/ContentPresenter.cs:line 362
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 40
   at Avalonia.Controls.Decorator.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Decorator.cs:line 54
   at Avalonia.Controls.Primitives.VisualLayerManager.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Primitives/VisualLayerManager.cs:line 136
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.Layoutable.MeasureOverride(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 625
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.Layoutable.MeasureOverride(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 625
   at Avalonia.Controls.Primitives.PopupRoot.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Primitives/PopupRoot.cs:line 137
   at Avalonia.Controls.WindowBase.MeasureCore(Size availableSize) in /_/src/Avalonia.Controls/WindowBase.cs:line 246
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.LayoutManager.Measure(ILayoutable control) in /_/src/Avalonia.Layout/LayoutManager.cs:line 287
   at Avalonia.Layout.LayoutManager.ExecuteInitialLayoutPass() in /_/src/Avalonia.Layout/LayoutManager.cs:line 174
   at Avalonia.Controls.WindowBase.Show() in /_/src/Avalonia.Controls/WindowBase.cs:line 162
   at Avalonia.Controls.Primitives.Popup.Open() in /_/src/Avalonia.Controls/Primitives/Popup.cs:line 474
   at Avalonia.Controls.Primitives.Popup.IsOpenChanged(AvaloniaPropertyChangedEventArgs`1 e) in /_/src/Avalonia.Controls/Primitives/Popup.cs:line 542
   at Avalonia.Controls.Primitives.Popup.<>c.<.cctor>b__22_1(Popup x, AvaloniaPropertyChangedEventArgs e) in /_/src/Avalonia.Controls/Primitives/Popup.cs:line 144
   at Avalonia.AvaloniaObjectExtensions.<>c__DisplayClass23_0`1.<AddClassHandler>b__0(AvaloniaPropertyChangedEventArgs e) in /_/src/Avalonia.Base/AvaloniaObjectExtensions.cs:line 583
   at System.Reactive.AnonymousObserver`1.OnNextCore(T value) in /_/Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs:line 67
   at System.Reactive.ObserverBase`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/ObserverBase.cs:line 34
   at System.Reactive.Subjects.Subject`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 147
   at Avalonia.AvaloniaProperty`1.NotifyChanged(AvaloniaPropertyChangedEventArgs`1 e) in /_/src/Avalonia.Base/AvaloniaProperty`1.cs:line 80
   at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 719
   at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaProperty`1 property, Optional`1 oldValue, BindingValue`1 newValue, BindingPriority priority) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 632
   at Avalonia.AvaloniaObject.SetAndRaise[T](AvaloniaProperty`1 property, T& field, T value) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 662
   at Avalonia.Controls.Primitives.Popup.set_IsOpen(Boolean value) in /_/src/Avalonia.Controls/Primitives/Popup.cs:line 206
   at Avalonia.Controls.Primitives.Popup.<>c.<.cctor>b__22_3(Popup o, Boolean v) in /_/src/Avalonia.Controls/Primitives/Popup.cs:line 38
   at Avalonia.DirectProperty`2.InvokeSetter(IAvaloniaObject instance, BindingValue`1 value) in /_/src/Avalonia.Base/DirectProperty.cs:line 172
   at Avalonia.AvaloniaObject.SetDirectValueUnchecked[T](DirectPropertyBase`1 property, BindingValue`1 value) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 797
   at Avalonia.AvaloniaObject.DirectBindingSubscription`1.OnNext(BindingValue`1 value) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 888
   at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value) in /_/src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs:line 50
   at Avalonia.Reactive.TypedBindingAdapter`1.OnNext(BindingValue`1 value) in /_/src/Avalonia.Base/Reactive/TypedBindingAdapter.cs:line 31
   at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value) in /_/src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs:line 50
   at Avalonia.Reactive.BindingValueAdapter`1.OnNext(T value) in /_/src/Avalonia.Base/Reactive/BindingValueAdapter.cs:line 18
   at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value) in /_/src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs:line 50
   at Avalonia.Data.TemplateBinding.PublishValue() in /_/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs:line 145
   at Avalonia.Data.TemplateBinding.TemplatedParentPropertyChanged(Object sender, AvaloniaPropertyChangedEventArgs e) in /_/src/Markup/Avalonia.Markup/Data/TemplateBinding.cs:line 183
   at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 720
   at Avalonia.AvaloniaObject.Avalonia.PropertyStore.IValueSink.ValueChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 491
   at Avalonia.ValueStore.SetExisting[T](Object slot, StyledPropertyBase`1 property, T value, BindingPriority priority) in /_/src/Avalonia.Base/ValueStore.cs:line 243
   at Avalonia.ValueStore.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority) in /_/src/Avalonia.Base/ValueStore.cs:line 87
   at Avalonia.AvaloniaObject.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 349
   at Avalonia.Controls.MenuItem.set_IsSubMenuOpen(Boolean value) in /_/src/Avalonia.Controls/MenuItem.cs:line 262
   at Avalonia.Controls.MenuItem.Open() in /_/src/Avalonia.Controls/MenuItem.cs:line 319
   at Avalonia.Controls.Platform.DefaultMenuInteractionHandler.Open(IMenuItem item, Boolean selectFirst) in /_/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs:line 482
   at Avalonia.Controls.Platform.DefaultMenuInteractionHandler.PointerPressed(Object sender, PointerPressedEventArgs e) in /_/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs:line 390
   at Avalonia.Interactivity.Interactive.<AddHandler>g__InvokeAdapter|4_0[TEventArgs](Delegate baseHandler, Object sender, RoutedEventArgs args) in /_/src/Avalonia.Interactivity/Interactive.cs:line 60
   at Avalonia.Interactivity.Interactive.<>c__4`1.<AddHandler>b__4_1(Delegate baseHandler, Object sender, RoutedEventArgs args) in /_/src/Avalonia.Interactivity/Interactive.cs:line 66
   at Avalonia.Interactivity.EventRoute.RaiseEventImpl(RoutedEventArgs e) in /_/src/Avalonia.Interactivity/EventRoute.cs:line 167
   at Avalonia.Interactivity.EventRoute.RaiseEvent(IInteractive source, RoutedEventArgs e) in /_/src/Avalonia.Interactivity/EventRoute.cs:line 101
   at Avalonia.Interactivity.Interactive.RaiseEvent(RoutedEventArgs e) in /_/src/Avalonia.Interactivity/Interactive.cs:line 120
   at Avalonia.Input.MouseDevice.MouseDown(IMouseDevice device, UInt64 timestamp, IInputElement root, Point p, PointerPointProperties properties, KeyModifiers inputModifiers) in /_/src/Avalonia.Input/MouseDevice.cs:line 254
   at Avalonia.Input.MouseDevice.ProcessRawEvent(RawPointerEventArgs e) in /_/src/Avalonia.Input/MouseDevice.cs:line 162
   at Avalonia.Input.MouseDevice.ProcessRawEvent(RawInputEventArgs e) in /_/src/Avalonia.Input/MouseDevice.cs:line 86
   at Avalonia.Input.InputManager.ProcessInput(RawInputEventArgs e) in /_/src/Avalonia.Input/InputManager.cs:line 35
   at Avalonia.Controls.TopLevel.HandleInput(RawInputEventArgs e) in /_/src/Avalonia.Controls/TopLevel.cs:line 476
   at Avalonia.X11.X11Window.<ScheduleInput>b__120_0() in /_/src/Avalonia.X11/X11Window.cs:line 719
   at Avalonia.Threading.JobRunner.Job.Avalonia.Threading.JobRunner.IJob.Run() in /_/src/Avalonia.Base/Threading/JobRunner.cs:line 166
   at Avalonia.Threading.JobRunner.RunJobs(Nullable`1 priority) in /_/src/Avalonia.Base/Threading/JobRunner.cs:line 37
   at Avalonia.Threading.Dispatcher.RunJobs() in /_/src/Avalonia.Base/Threading/Dispatcher.cs:line 69
   at Avalonia.X11.X11PlatformThreading.HandleX11(CancellationToken cancellationToken) in /_/src/Avalonia.X11/X11PlatformThreading.cs:line 199
   at Avalonia.X11.X11PlatformThreading.RunLoop(CancellationToken cancellationToken) in /_/src/Avalonia.X11/X11PlatformThreading.cs:line 245
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken) in /_/src/Avalonia.Base/Threading/Dispatcher.cs:line 61
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 107
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 134
   at Citrus.Avalonia.Sandbox.Program.Main(String[] args) in /home/emmaus/personal/Citrus.Avalonia/src/Citrus.Avalonia.Sandbox/Program.cs:line 11

This issue can be reproduced in this repo. https://github.com/emmauss/Citrus.Avalonia

To Reproduce
Steps to reproduce the behavior:

  1. Open one of the menus. The sub menu will show.
  2. Click Switch theme to change style.
  3. Reopen the menu in 1.

Expected behavior
The menu shows with the currently applied style

Desktop (please complete the following information):

  • OS: Linux
  • Version 0.10.0
@danik-ik
Copy link

danik-ik commented May 7, 2021

Similar problem with ComboBox.

A simple actions sequence that is guaranteed to lead to an error:

  1. open and close any ComboBox;
  2. change the theme (Fluent dark/light, or one of Citrus.Avalonia themes);
  3. open the ComboBox again

When a ComboBox is created for the first time, ComboBoxItems are inserted into popup. After changing the theme, the same ComboBoxItems (already having a parent) are re-inserted into newly created popup, resulting in an exception (Visual.cs:line 554).

Minimal sample, without any external dependencies (switching built-in fluent themes) is here: https://bitbucket.org/danik-ik/avaloniaui.issue.5685

Please also note: in the example where the Fluent theme changes,

  1. we are forced to add one (any) Fluent theme to the App.axaml, otherwise the application crashes at startup (but with Citrus.Avalonia themes there is not the same problem);
  2. If a light Fluent theme is preloaded in App.axaml, and a dark one is programmatically initiated, the popup of the ComboBox will be light.
    This problem may be in the implementation of the theme itself, or in the implementation of software loading. Unfortunately, I don't have enough insight into Avalonia from the inside to localize the problem right away.

It might also be useful: switching between «default» built-in themes (same repository at tag «0») does NOT generate an error

@Splitwirez
Copy link
Contributor

Splitwirez commented May 31, 2021

I think I just ran into this issue as well: wieslawsoltes/Dock#198

@JaggerJo
Copy link
Contributor

Just ran into this issue. What's the current state of the bug?

@maxkatz6
Copy link
Member

Dup of #4839

Caused by materialized controls used as items source, which can't be reused with another parent (after theme was switched, template with itemspresenter is replaced)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants