Open nitroxis opened 1 year ago
I tried setting InheritTransform = true
in FlyoutBase.CreatePopup
, which seems to work as far as scaling is concered. However, this causes an exception when the user resizes the Viewbox while the popup is opened:
System.InvalidOperationException: Visual was invalidated during a render pass
at Avalonia.Rendering.DirtyVisuals.Add(IVisual visual) in Avalonia\src\Avalonia.Base\Rendering\DirtyVisuals.cs:line 35
at Avalonia.Rendering.DeferredRenderer.AddDirty(IVisual visual) in Avalonia\src\Avalonia.Base\Rendering\DeferredRenderer.cs:line 121
at Avalonia.Visual.InvalidateVisual() in Avalonia\src\Avalonia.Base\Visual.cs:line 329
at Avalonia.Layout.Layoutable.InvalidateMeasure() in Avalonia\src\Avalonia.Base\Layout\Layoutable.cs:line 428
at Avalonia.Controls.LayoutTransformControl.ApplyLayoutTransform() in Avalonia\src\Avalonia.Controls\LayoutTransformControl.cs:line 272
at Avalonia.Controls.LayoutTransformControl.OnLayoutTransformChanged(AvaloniaPropertyChangedEventArgs e) in Avalonia\src\Avalonia.Controls\LayoutTransformControl.cs:line 432
at Avalonia.Controls.LayoutTransformControl.<>c.<.cctor>b__2_0(LayoutTransformControl x, AvaloniaPropertyChangedEventArgs e) in Avalonia\src\Avalonia.Controls\LayoutTransformControl.cs:line 28
at Avalonia.AvaloniaObjectExtensions.<>c__DisplayClass16_0`1.<AddClassHandler>b__0(AvaloniaPropertyChangedEventArgs e) in Avalonia\src\Avalonia.Base\AvaloniaObjectExtensions.cs:line 442
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 Avalonia\src\Avalonia.Base\AvaloniaProperty`1.cs:line 65
at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 779
at Avalonia.AvaloniaObject.ValueChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 551
at Avalonia.ValueStore.ValueChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in Avalonia\src\Avalonia.Base\ValueStore.cs:line 235
at Avalonia.PropertyStore.ValueOwner`1.ValueChanged(AvaloniaPropertyChangedEventArgs`1 e) in Avalonia\src\Avalonia.Base\PropertyStore\ValueOwner.cs:line 40
at Avalonia.PropertyStore.BindingEntry`1.UpdateValue(BindingValue`1 value) in Avalonia\src\Avalonia.Base\PropertyStore\BindingEntry.cs:line 151
at Avalonia.PropertyStore.BindingEntry`1.OnNext(BindingValue`1 value) in Avalonia\src\Avalonia.Base\PropertyStore\BindingEntry.cs:line 87
at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value) in Avalonia\src\Avalonia.Base\Reactive\SingleSubscriberObservableBase.cs:line 49
at Avalonia.Reactive.TypedBindingAdapter`1.OnNext(BindingValue`1 value) in Avalonia\src\Avalonia.Base\Reactive\TypedBindingAdapter.cs:line 29
at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value) in Avalonia\src\Avalonia.Base\Reactive\SingleSubscriberObservableBase.cs:line 49
at Avalonia.Reactive.BindingValueAdapter`1.OnNext(T value) in Avalonia\src\Avalonia.Base\Reactive\BindingValueAdapter.cs:line 16
at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value) in Avalonia\src\Avalonia.Base\Reactive\SingleSubscriberObservableBase.cs:line 49
at Avalonia.Data.TemplateBinding.PublishValue() in Avalonia\src\Markup\Avalonia.Markup\Data\TemplateBinding.cs:line 146
at Avalonia.Data.TemplateBinding.TemplatedParentPropertyChanged(Object sender, AvaloniaPropertyChangedEventArgs e) in Avalonia\src\Markup\Avalonia.Markup\Data\TemplateBinding.cs:line 183
at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 780
at Avalonia.AvaloniaObject.ValueChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 551
at Avalonia.ValueStore.NotifyValueChanged[T](AvaloniaProperty`1 property, Optional`1 oldValue, BindingValue`1 newValue, BindingPriority priority) in Avalonia\src\Avalonia.Base\ValueStore.cs:line 354
at Avalonia.ValueStore.SetExisting[T](Object slot, StyledPropertyBase`1 property, T value, BindingPriority priority) in Avalonia\src\Avalonia.Base\ValueStore.cs:line 264
at Avalonia.ValueStore.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority) in Avalonia\src\Avalonia.Base\ValueStore.cs:line 96
at Avalonia.AvaloniaObject.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 368
at Avalonia.Controls.Primitives.OverlayPopupHost.set_Transform(Transform value) in Avalonia\src\Avalonia.Controls\Primitives\OverlayPopupHost.cs:line 42
at Avalonia.Controls.Primitives.Popup.UpdateHostSizing(IPopupHost popupHost, TopLevel topLevel, IControl placementTarget) in Avalonia\src\Avalonia.Controls\Primitives\Popup.cs:line 597
at Avalonia.Controls.Primitives.Popup.PlacementTargetPropertyChanged(Object sender, AvaloniaPropertyChangedEventArgs e) in Avalonia\src\Avalonia.Controls\Primitives\Popup.cs:line 882
at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 780
at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaProperty`1 property, Optional`1 oldValue, BindingValue`1 newValue, BindingPriority priority) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 691
at Avalonia.AvaloniaObject.SetAndRaise[T](AvaloniaProperty`1 property, T& field, T value) in Avalonia\src\Avalonia.Base\AvaloniaObject.cs:line 721
at Avalonia.Visual.Avalonia.VisualTree.IVisual.set_TransformedBounds(Nullable`1 value) in Avalonia\src\Avalonia.Base\Visual.cs:line 321
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 262
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 306
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 299
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 306
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, Boolean forceRecurse) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 273
at Avalonia.Rendering.SceneGraph.SceneBuilder.Update(Scene scene, IVisual visual) in Avalonia\src\Avalonia.Base\Rendering\SceneGraph\SceneBuilder.cs:line 91
at Avalonia.Rendering.DeferredRenderer.UpdateScene() in Avalonia\src\Avalonia.Base\Rendering\DeferredRenderer.cs:line 661
at Avalonia.Rendering.DeferredRenderer.Paint(Rect rect) in Avalonia\src\Avalonia.Base\Rendering\DeferredRenderer.cs:line 222
at Avalonia.Controls.TopLevel.HandlePaint(Rect rect) in Avalonia\src\Avalonia.Controls\TopLevel.cs:line 374
I tried setting InheritTransform = true in FlyoutBase.CreatePopup, which seems to work as far as scaling is concered
Yes, that's correct IIRC. @grokys
However, this causes an exception when the user resizes the Viewbox while the popup is opened:
Try to replace line 883 on Popup:
UpdateHostSizing(_openState.PopupHost, _openState.TopLevel, _openState.PlacementTarget);
with
Dispatcher.UIThread.Post(() => UpdateHostSizing(_openState.PopupHost, _openState.TopLevel, _openState.PlacementTarget));
Changing that line does fix the exception.
There is one other problem: Resizing the Viewbox does not reposition the Popup to stay aligned with the Button. It does scale up/down though.
Also, when using a MenuFlyout, sub-menus don't seem to have InheritTransform set to true. On sub-popups this property should probably be set to the same value as the parent, in general?
Another possible solution would be to put a VisualLayerManager inside the Viewbox so popups use this as their container. Then it would be necessary to change PopupPositionerExtensions.ConfigurePosition so that it can compute transforms relative to it (e.g. supply the overlay container as an argument)
Describe the bug Placing a Flyout inside a Button which is itself inside a Viewbox leads to the flyout not respecting the Viewbox' transform.
To Reproduce Do something like:
The button will be scaled up to fit the viewbox, but the flyout is very tiny in comparison.
Expected behavior The flyout should have the same scaling as the button, or at least have an option to enable such behavior.
Screenshots
Desktop (please complete the following information):