diff --git a/src/Avalonia.Controls/AutoCompleteBox.cs b/src/Avalonia.Controls/AutoCompleteBox.cs index bfd633c947..b59fd7abde 100644 --- a/src/Avalonia.Controls/AutoCompleteBox.cs +++ b/src/Avalonia.Controls/AutoCompleteBox.cs @@ -1405,8 +1405,11 @@ namespace Avalonia.Controls break; case Key.Enter: - OnAdapterSelectionComplete(this, new RoutedEventArgs()); - e.Handled = true; + if (IsDropDownOpen) + { + OnAdapterSelectionComplete(this, new RoutedEventArgs()); + e.Handled = true; + } break; default: diff --git a/src/Avalonia.Visuals/Matrix.cs b/src/Avalonia.Visuals/Matrix.cs index 2ccfd43f03..8136f843df 100644 --- a/src/Avalonia.Visuals/Matrix.cs +++ b/src/Avalonia.Visuals/Matrix.cs @@ -282,25 +282,44 @@ namespace Avalonia } /// - /// Inverts the Matrix. + /// Attempts to invert the Matrix. /// - /// The inverted matrix. - public Matrix Invert() + /// The inverted matrix or when matrix is not invertible. + public bool TryInvert(out Matrix inverted) { double d = GetDeterminant(); if (MathUtilities.IsZero(d)) { - throw new InvalidOperationException("Transform is not invertible."); + inverted = default; + + return false; } - return new Matrix( + inverted = new Matrix( _m22 / d, -_m12 / d, -_m21 / d, _m11 / d, ((_m21 * _m32) - (_m22 * _m31)) / d, ((_m12 * _m31) - (_m11 * _m32)) / d); + + return true; + } + + /// + /// Inverts the Matrix. + /// + /// Matrix is not invertible. + /// The inverted matrix. + public Matrix Invert() + { + if (!TryInvert(out Matrix inverted)) + { + throw new InvalidOperationException("Transform is not invertible."); + } + + return inverted; } /// diff --git a/src/Avalonia.Visuals/VisualExtensions.cs b/src/Avalonia.Visuals/VisualExtensions.cs index 6079e5941f..e6523a1469 100644 --- a/src/Avalonia.Visuals/VisualExtensions.cs +++ b/src/Avalonia.Visuals/VisualExtensions.cs @@ -50,7 +50,13 @@ namespace Avalonia { var thisOffset = GetOffsetFrom(common, from); var thatOffset = GetOffsetFrom(common, to); - return -thatOffset * thisOffset; + + if (!thatOffset.TryInvert(out var thatOffsetInverted)) + { + return null; + } + + return thatOffsetInverted * thisOffset; } return null; diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTests.cs b/tests/Avalonia.Visuals.UnitTests/VisualTests.cs index 447a68aa69..38131fbfca 100644 --- a/tests/Avalonia.Visuals.UnitTests/VisualTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/VisualTests.cs @@ -235,6 +235,25 @@ namespace Avalonia.Visuals.UnitTests Assert.Equal(new Point(100, 100), point); } + [Fact] + public void TransformToVisual_With_NonInvertible_RenderTransform_Should_Work() + { + var child = new Decorator + { + Width = 100, + Height = 100, + RenderTransform = new ScaleTransform() { ScaleX = 0, ScaleY = 0 } + }; + var root = new TestRoot() { Child = child, Width = 400, Height = 400 }; + + root.Measure(Size.Infinity); + root.Arrange(new Rect(new Point(), root.DesiredSize)); + + var tr = root.TransformToVisual(child); + + Assert.Null(tr); + } + [Fact] public void Should_Not_Log_Binding_Error_When_Not_Attached_To_Logical_Tree() {