AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.11k stars 2.26k forks source link

Scroll ListBox inside neasted grids: System.InvalidOperationException: 'The control already has a visual parent.' #4817

Closed sn4k3 closed 4 years ago

sn4k3 commented 4 years ago

I'm getting this error when scroll a ListBox or resize the window containing the listbox on neasted grids:

at Avalonia.Visual.ValidateVisualChild(IVisual c) at Avalonia.Visual.<>c.<.ctor>b16_0(IVisual visual) at Avalonia.Collections.AvaloniaList`1.Add(T item) at Avalonia.Controls.Presenters.ContentPresenter.UpdateChild() at Avalonia.Controls.Presenters.ContentPresenter.ContentChanged(AvaloniaPropertyChangedEventArgs e) at Avalonia.Controls.Presenters.ContentPresenter.<>c.<.cctor>b__15_0(ContentPresenter x, AvaloniaPropertyChangedEventArgs e) at Avalonia.AvaloniaObjectExtensions.<>cDisplayClass23_01.<AddClassHandler>b__0(AvaloniaPropertyChangedEventArgs e) at System.Reactive.Subjects.Subject1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 148 at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs1 change) at Avalonia.AvaloniaObject.Avalonia.PropertyStore.IValueSink.ValueChanged[T](AvaloniaPropertyChangedEventArgs1 change) at Avalonia.PropertyStore.BindingEntry1.UpdateValue(BindingValue1 value) at Avalonia.PropertyStore.BindingEntry1.OnNext(BindingValue1 value) at Avalonia.Reactive.SingleSubscriberObservableBase1.PublishNext(T value) at Avalonia.Reactive.BindingValueAdapter1.OnNext(T value) at Avalonia.Reactive.SingleSubscriberObservableBase1.PublishNext(T value) at Avalonia.Data.TemplateBinding.PublishValue() at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs1 change) at Avalonia.AvaloniaObject.Avalonia.PropertyStore.IValueSink.ValueChanged[T](AvaloniaPropertyChangedEventArgs1 change) at Avalonia.PropertyStore.PriorityValue1.UpdateEffectiveValue(AvaloniaPropertyChangedEventArgs1 change) at Avalonia.PropertyStore.PriorityValue1.SetValue(T value, BindingPriority priority) at Avalonia.ValueStore.SetExisting[T](Object slot, StyledPropertyBase1 property, T value, BindingPriority priority) at Avalonia.ValueStore.SetValue[T](StyledPropertyBase1 property, T value, BindingPriority priority) at Avalonia.StyledPropertyBase1.RouteSetValue(IAvaloniaObject o, Object value, BindingPriority priority) at Avalonia.AvaloniaObjectExtensions.SetValue(IAvaloniaObject target, AvaloniaProperty property, Object value, BindingPriority priority) at Avalonia.Controls.Generators.ItemContainerGenerator1.TryRecycle(Int32 oldIndex, Int32 newIndex, Object item) at Avalonia.Controls.Presenters.ItemVirtualizerSimple.RecycleContainersForMove(Int32 delta) at Avalonia.Controls.Presenters.ItemVirtualizerSimple.set_OffsetValue(Double value) at Avalonia.Controls.Presenters.ItemVirtualizer.set_Offset(Vector value) at Avalonia.Controls.Presenters.ItemsPresenter.Avalonia.Controls.Primitives.IScrollable.set_Offset(Vector value) at Avalonia.Controls.Presenters.ScrollContentPresenter.<>cDisplayClass50_0.b_2(Vector x) at System.Reactive.AnonymousSafeObserver`1.OnNext(T value) in //Rx.NET/Source/src/System.Reactive/AnonymousSafeObserver.cs:line 44 at System.Reactive.Sink1.ForwardOnNext(TTarget value) in /_/Rx.NET/Source/src/System.Reactive/Internal/Sink.cs:line 50 at System.Reactive.Linq.ObservableImpl.Skip1.Count..OnNext(TSource value) in //Rx.NET/Source/src/System.Reactive/Linq/Observable/Skip.cs:line 59 at Avalonia.Reactive.LightweightObservableBase1.PublishNext(T value) at Avalonia.Reactive.AvaloniaPropertyObservable1.PropertyChanged(Object sender, AvaloniaPropertyChangedEventArgs e) at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs1 change) at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaProperty1 property, Optional1 oldValue, BindingValue1 newValue, BindingPriority priority) at Avalonia.AvaloniaObject.SetAndRaise[T](AvaloniaProperty`1 property, T& field, T value) at Avalonia.Controls.Presenters.ScrollContentPresenter.set_Offset(Vector value) at Avalonia.Controls.Presenters.ScrollContentPresenter.OnPointerWheelChanged(PointerWheelEventArgs e) at Avalonia.Input.InputElement.<>c.<.cctor>b2611(InputElement x, PointerWheelEventArgs e) at System.Reactive.AnonymousObserver`1.OnNextCore(T value) in //Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs:line 67 at System.Reactive.ObserverBase1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/ObserverBase.cs:line 36 at System.Reactive.Subjects.Subject1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 150 at Avalonia.Interactivity.EventRoute.RaiseEventImpl(RoutedEventArgs e) at Avalonia.Interactivity.EventRoute.RaiseEvent(IInteractive source, RoutedEventArgs e) at Avalonia.Interactivity.Interactive.RaiseEvent(RoutedEventArgs e) at Avalonia.Input.MouseDevice.MouseWheel(IMouseDevice device, UInt64 timestamp, IInputRoot root, Point p, PointerPointProperties props, Vector delta, KeyModifiers inputModifiers) at Avalonia.Input.MouseDevice.ProcessRawEvent(RawPointerEventArgs e) at Avalonia.Input.InputManager.ProcessInput(RawInputEventArgs e) at Avalonia.Win32.WindowImpl.AppWndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam) at Avalonia.Win32.WindowImpl.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam) at Avalonia.Win32.Interop.UnmanagedMethods.DispatchMessage(MSG& lpmsg) at Avalonia.Win32.Win32Platform.RunLoop(CancellationToken cancellationToken) at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken) at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args) at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode) at UVtools.WPF.Program.Main(String[] args) in D:\Tiago\Dropbox\Programming\C#\UVtools\UVtools.WPF\Program.cs:line 17

image AXAML: https://github.com/sn4k3/UVtools/blob/master/UVtools.WPF/Windows/PrusaSlicerManager.axaml

image

maxkatz6 commented 4 years ago

Your ListBox.Items is bind to a list of ComboBox controls. I think this exception occurs when Avalonia tries to change ComboBox parent for virtualization. Try to set <ListBox VirtualizationMode="None" ... > as a workaround.

It seems to be a bug in ListBox VirtualizationMode=Simple, that is enabled by default. I believe, migration to ItemsRepeater in the ListBox internals should fix this problem. https://github.com/AvaloniaUI/Avalonia/pull/4779

By the way, it's more common way to use ItemTemplate with the ListBox - https://avaloniaui.net/docs/controls/listbox. You can define ComboBox in that template, and configure TwoWay binding to your model.

sn4k3 commented 4 years ago

VirtualizationMode="None" worked.

By the way, it's more common way to use ItemTemplate with the ListBox - https://avaloniaui.net/docs/controls/listbox. You can define ComboBox in that template, and configure TwoWay binding to your model.

Thank you for the tip, i will take a look

I will keep the issue open as it seens a real issue, fell free to close it if not

maxkatz6 commented 4 years ago

It is a real issue, but there is another one with same bug - https://github.com/AvaloniaUI/Avalonia/issues/4265 Closing this one.