From 03e01a6e554227613ce5579cf24884e8a94ad629 Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Mon, 30 May 2022 13:04:46 +0300 Subject: [PATCH 1/8] initial working --- src/Avalonia.Controls/ComboBox.cs | 21 ++-- src/Avalonia.Controls/Control.cs | 7 +- .../Rendering/SceneGraph/SceneBuilderTests.cs | 33 +++++++ .../ComboBoxTests.cs | 99 +++++++++++++++++++ .../FlowDirectionTests.cs | 41 ++++++++ 5 files changed, 181 insertions(+), 20 deletions(-) create mode 100644 tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index cbf9b35a05..1f46a3b292 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -184,23 +184,10 @@ namespace Avalonia.Controls this.UpdateSelectionBoxItem(SelectedItem); } - // Because the SelectedItem isn't connected to the visual tree public override void InvalidateMirrorTransform() { base.InvalidateMirrorTransform(); - - if (SelectedItem is Control selectedControl) - { - selectedControl.InvalidateMirrorTransform(); - - foreach (var visual in selectedControl.GetVisualDescendants()) - { - if (visual is Control childControl) - { - childControl.InvalidateMirrorTransform(); - } - } - } + UpdateSelectionBoxItem(SelectedItem); } /// @@ -365,6 +352,8 @@ namespace Avalonia.Controls { parent.GetObservable(IsVisibleProperty).Subscribe(IsVisibleChanged).DisposeWith(_subscriptionsOnOpen); } + + UpdateSelectionBoxItem(SelectedItem); } private void IsVisibleChanged(bool isVisible) @@ -420,8 +409,12 @@ namespace Avalonia.Controls { control.Measure(Size.Infinity); + var flowDirection = control.IsAttachedToVisualTree ? + (control.VisualParent as Control)!.FlowDirection : FlowDirection.LeftToRight; + SelectionBoxItem = new Rectangle { + FlowDirection = flowDirection, Width = control.DesiredSize.Width, Height = control.DesiredSize.Height, Fill = new VisualBrush diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs index d6a5fa0727..16d4ef5c15 100644 --- a/src/Avalonia.Controls/Control.cs +++ b/src/Avalonia.Controls/Control.cs @@ -378,17 +378,12 @@ namespace Avalonia.Controls bool bypassFlowDirectionPolicies = BypassFlowDirectionPolicies; bool parentBypassFlowDirectionPolicies = false; - var parent = this.FindAncestorOfType(); + var parent = ((IVisual)this).VisualParent as Control; if (parent != null) { parentFlowDirection = parent.FlowDirection; parentBypassFlowDirectionPolicies = parent.BypassFlowDirectionPolicies; } - else if (Parent is Control logicalParent) - { - parentFlowDirection = logicalParent.FlowDirection; - parentBypassFlowDirectionPolicies = logicalParent.BypassFlowDirectionPolicies; - } bool thisShouldBeMirrored = flowDirection == FlowDirection.RightToLeft && !bypassFlowDirectionPolicies; bool parentShouldBeMirrored = parentFlowDirection == FlowDirection.RightToLeft && !parentBypassFlowDirectionPolicies; diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs index 01afe85b8b..5cc9f57c8e 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs @@ -349,6 +349,39 @@ namespace Avalonia.Base.UnitTests.Rendering.SceneGraph } } + [Fact] + public void MirrorTransform_For_Control_With_RenderTransform_Should_Be_Correct() + { + using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) + { + Border border; + var tree = new TestRoot + { + Width = 400, + Height = 200, + Child = border = new Border + { + HorizontalAlignment = HorizontalAlignment.Left, + Background = Brushes.Red, + Width = 100, + RenderTransform = new ScaleTransform(0.5, 1), + FlowDirection = FlowDirection.RightToLeft + } + }; + + tree.Measure(Size.Infinity); + tree.Arrange(new Rect(tree.DesiredSize)); + + var scene = new Scene(tree); + var sceneBuilder = new SceneBuilder(); + sceneBuilder.UpdateAll(scene); + + var expectedTransform = new Matrix(-1, 0, 0, 1, 100, 0) * Matrix.CreateScale(0.5, 1) * Matrix.CreateTranslation(25, 0); + var borderNode = scene.FindNode(border); + Assert.Equal(expectedTransform, borderNode.Transform); + } + } + [Fact] public void Should_Update_Border_Background_Node() { diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index 98695fe88e..0f1925f628 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -336,5 +336,104 @@ namespace Avalonia.Controls.UnitTests Assert.Equal(1, count); } } + + [Fact] + public void FlowDirection_Of_RectangleContent_Shuold_Be_LeftToRight() + { + using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) + { + var items = new[] + { + new ComboBoxItem() + { + Content = new Control() + } + }; + var target = new ComboBox + { + Items = items, + Template = GetTemplate() + }; + + var root = new TestRoot(target); + target.ApplyTemplate(); + target.SelectedIndex = 0; + + var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; + + Assert.Equal(FlowDirection.LeftToRight, rectangle.FlowDirection); + } + } + + [Fact] + public void FlowDirection_Of_RectangleContent_Updated_After_Change_ComboBox() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var items = new[] + { + new ComboBoxItem() + { + Content = new Control() + } + }; + var target = new ComboBox + { + FlowDirection = FlowDirection.RightToLeft, + Items = items, + Template = GetTemplate() + }; + + var root = new TestRoot(target); + + target.ApplyTemplate(); + target.Presenter.ApplyTemplate(); + target.SelectedIndex = 0; + + var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; + + // need help here, the 'rectangle' isn't connected to visual tree for some reason + + Assert.True(rectangle.HasMirrorTransform); + + target.FlowDirection = FlowDirection.LeftToRight; + + Assert.False(rectangle.HasMirrorTransform); + } + } + + [Fact] + public void FlowDirection_Of_RectangleContent_Updated_After_Content_In_VisualTree() + { + using (UnitTestApplication.Start(TestServices.RealFocus)) + { + Control content; + var items = new[] + { + new ComboBoxItem() + { + Content = content = new Control() + } + }; + var target = new ComboBox + { + FlowDirection = FlowDirection.RightToLeft, + Items = items, + Template = GetTemplate() + }; + + var root = new TestRoot(target); + target.ApplyTemplate(); + target.Presenter.ApplyTemplate(); + target.SelectedIndex = 0; + + // need help here how to connect 'content' tio visual tree, or how to + + + var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; + + Assert.Equal(FlowDirection.RightToLeft, rectangle.FlowDirection); + } + } } } diff --git a/tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs b/tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs new file mode 100644 index 0000000000..6739eff638 --- /dev/null +++ b/tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs @@ -0,0 +1,41 @@ +using Avalonia.Media; +using Xunit; + +namespace Avalonia.Controls.UnitTests +{ + public class FlowDirectionTests + { + [Fact] + public void HasMirrorTransform_Should_Be_True() + { + var target = new Control + { + FlowDirection = FlowDirection.RightToLeft, + }; + + Assert.True(target.HasMirrorTransform); + } + + [Fact] + public void HasMirrorTransform_Of_Children_Is_Updated_After_Change() + { + Control child; + var target = new Decorator + { + FlowDirection = FlowDirection.LeftToRight, + Child = child = new Control() + { + FlowDirection = FlowDirection.LeftToRight, + } + }; + + Assert.False(target.HasMirrorTransform); + Assert.False(child.HasMirrorTransform); + + target.FlowDirection = FlowDirection.RightToLeft; + + Assert.True(target.HasMirrorTransform); + Assert.True(child.HasMirrorTransform); + } + } +} From 05db047d2909b96b264ffded9e882bb62278ba25 Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Mon, 30 May 2022 13:09:20 +0300 Subject: [PATCH 2/8] typo --- tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index 0f1925f628..905ded193c 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -427,7 +427,7 @@ namespace Avalonia.Controls.UnitTests target.Presenter.ApplyTemplate(); target.SelectedIndex = 0; - // need help here how to connect 'content' tio visual tree, or how to + // need help here how to connect 'content' to visual tree, or how to open popup var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; From ee4c0f97e6e4000f01a46b591ed43afa4eba939b Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Mon, 30 May 2022 14:23:13 +0300 Subject: [PATCH 3/8] remove OnAttachedToVisualTree because bug --- src/Avalonia.Controls/ComboBox.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index 1f46a3b292..8a6fb361da 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -178,16 +178,10 @@ namespace Avalonia.Controls ComboBoxItem.ContentTemplateProperty); } - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - this.UpdateSelectionBoxItem(SelectedItem); - } - public override void InvalidateMirrorTransform() { base.InvalidateMirrorTransform(); - UpdateSelectionBoxItem(SelectedItem); + UpdateSelectionBoxItem(SelectedItem); } /// From 7e6edb0f32b753d226aba58889d56c2875b6f282 Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Mon, 30 May 2022 23:42:05 +0300 Subject: [PATCH 4/8] fixes bugs --- src/Avalonia.Controls/ComboBox.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index 8a6fb361da..a3f87f7695 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -403,8 +403,8 @@ namespace Avalonia.Controls { control.Measure(Size.Infinity); - var flowDirection = control.IsAttachedToVisualTree ? - (control.VisualParent as Control)!.FlowDirection : FlowDirection.LeftToRight; + var flowDirection = + (control.VisualParent as Control)?.FlowDirection ?? FlowDirection.LeftToRight; SelectionBoxItem = new Rectangle { From 402790ba86bfb6fc0f9de817cb3032b681175f38 Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Tue, 31 May 2022 07:53:59 +0300 Subject: [PATCH 5/8] improve UpdateFlowDirection --- src/Avalonia.Controls/ComboBox.cs | 28 +++++++++++++++---- .../ComboBoxTests.cs | 5 ++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index a3f87f7695..fc7feca7f1 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -178,10 +178,16 @@ namespace Avalonia.Controls ComboBoxItem.ContentTemplateProperty); } + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + UpdateSelectionBoxItem(SelectedItem); + } + public override void InvalidateMirrorTransform() { base.InvalidateMirrorTransform(); - UpdateSelectionBoxItem(SelectedItem); + UpdateFlowDirection(); } /// @@ -347,7 +353,7 @@ namespace Avalonia.Controls parent.GetObservable(IsVisibleProperty).Subscribe(IsVisibleChanged).DisposeWith(_subscriptionsOnOpen); } - UpdateSelectionBoxItem(SelectedItem); + UpdateFlowDirection(); } private void IsVisibleChanged(bool isVisible) @@ -403,12 +409,8 @@ namespace Avalonia.Controls { control.Measure(Size.Infinity); - var flowDirection = - (control.VisualParent as Control)?.FlowDirection ?? FlowDirection.LeftToRight; - SelectionBoxItem = new Rectangle { - FlowDirection = flowDirection, Width = control.DesiredSize.Width, Height = control.DesiredSize.Height, Fill = new VisualBrush @@ -419,6 +421,8 @@ namespace Avalonia.Controls } }; } + + UpdateFlowDirection(); } else { @@ -426,6 +430,18 @@ namespace Avalonia.Controls } } + private void UpdateFlowDirection() + { + var rectangle = SelectionBoxItem as Rectangle; + if (rectangle != null) + { + var content = (rectangle.Fill as VisualBrush)!.Visual as Control; + var flowDirection = (((IVisual)content!).VisualParent as Control)?.FlowDirection ?? FlowDirection.LeftToRight; + + rectangle.FlowDirection = flowDirection; + } + } + private void SelectFocusedItem() { foreach (ItemContainerInfo dropdownItem in ItemContainerGenerator.Containers) diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index 905ded193c..0804de3174 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -351,6 +351,7 @@ namespace Avalonia.Controls.UnitTests }; var target = new ComboBox { + FlowDirection = FlowDirection.RightToLeft, Items = items, Template = GetTemplate() }; @@ -368,7 +369,7 @@ namespace Avalonia.Controls.UnitTests [Fact] public void FlowDirection_Of_RectangleContent_Updated_After_Change_ComboBox() { - using (UnitTestApplication.Start(TestServices.StyledWindow)) + using (UnitTestApplication.Start(TestServices.RealStyler)) { var items = new[] { @@ -385,10 +386,10 @@ namespace Avalonia.Controls.UnitTests }; var root = new TestRoot(target); - target.ApplyTemplate(); target.Presenter.ApplyTemplate(); target.SelectedIndex = 0; + ((ContentPresenter)target.Presenter).UpdateChild(); var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; From c77c500bcd373fa3715cce5d5a851eaab89da408 Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Tue, 31 May 2022 14:35:55 +0300 Subject: [PATCH 6/8] fixes tests --- src/Avalonia.Controls/ComboBox.cs | 6 +- .../ComboBoxTests.cs | 116 +++++++++--------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index fc7feca7f1..5ba1195159 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -432,11 +432,11 @@ namespace Avalonia.Controls private void UpdateFlowDirection() { - var rectangle = SelectionBoxItem as Rectangle; - if (rectangle != null) + if (SelectionBoxItem is Rectangle rectangle) { var content = (rectangle.Fill as VisualBrush)!.Visual as Control; - var flowDirection = (((IVisual)content!).VisualParent as Control)?.FlowDirection ?? FlowDirection.LeftToRight; + var flowDirection = (((IVisual)content!).VisualParent as Control)?.FlowDirection ?? + FlowDirection.LeftToRight; rectangle.FlowDirection = flowDirection; } diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index 0804de3174..70b713d6d0 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -8,7 +8,7 @@ using Avalonia.Data; using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Media; -using Avalonia.Threading; +using Avalonia.VisualTree; using Avalonia.UnitTests; using Xunit; @@ -340,80 +340,77 @@ namespace Avalonia.Controls.UnitTests [Fact] public void FlowDirection_Of_RectangleContent_Shuold_Be_LeftToRight() { - using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) + var items = new[] { - var items = new[] - { - new ComboBoxItem() - { - Content = new Control() - } - }; - var target = new ComboBox - { - FlowDirection = FlowDirection.RightToLeft, - Items = items, - Template = GetTemplate() - }; + new ComboBoxItem() + { + Content = new Control() + } + }; + var target = new ComboBox + { + FlowDirection = FlowDirection.RightToLeft, + Items = items, + Template = GetTemplate() + }; - var root = new TestRoot(target); - target.ApplyTemplate(); - target.SelectedIndex = 0; + var root = new TestRoot(target); + target.ApplyTemplate(); + target.SelectedIndex = 0; - var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; + var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; - Assert.Equal(FlowDirection.LeftToRight, rectangle.FlowDirection); - } + Assert.Equal(FlowDirection.LeftToRight, rectangle.FlowDirection); } [Fact] - public void FlowDirection_Of_RectangleContent_Updated_After_Change_ComboBox() + public void FlowDirection_Of_RectangleContent_Updated_After_InvalidateMirrorTransform() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var parentContent = new Decorator() { - var items = new[] - { - new ComboBoxItem() - { - Content = new Control() - } - }; - var target = new ComboBox + Child = new Control() + }; + var items = new[] + { + new ComboBoxItem() { - FlowDirection = FlowDirection.RightToLeft, - Items = items, - Template = GetTemplate() - }; - - var root = new TestRoot(target); - target.ApplyTemplate(); - target.Presenter.ApplyTemplate(); - target.SelectedIndex = 0; - ((ContentPresenter)target.Presenter).UpdateChild(); - - var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; - - // need help here, the 'rectangle' isn't connected to visual tree for some reason + Content = parentContent.Child + } + }; + var target = new ComboBox + { + FlowDirection = FlowDirection.RightToLeft, + Items = items, + Template = GetTemplate() + }; - Assert.True(rectangle.HasMirrorTransform); + var root = new TestRoot(target); + target.ApplyTemplate(); + target.SelectedIndex = 0; - target.FlowDirection = FlowDirection.LeftToRight; + var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; + Assert.Equal(FlowDirection.LeftToRight, rectangle.FlowDirection); - Assert.False(rectangle.HasMirrorTransform); - } + parentContent.FlowDirection = FlowDirection.RightToLeft; + target.InvalidateMirrorTransform(); + + Assert.Equal(FlowDirection.RightToLeft, rectangle.FlowDirection); } [Fact] - public void FlowDirection_Of_RectangleContent_Updated_After_Content_In_VisualTree() + public void FlowDirection_Of_RectangleContent_Updated_After_OpenPopup() { - using (UnitTestApplication.Start(TestServices.RealFocus)) + using (UnitTestApplication.Start(TestServices.StyledWindow)) { - Control content; - var items = new[] + var parentContent = new Decorator() { + Child = new Control() + }; + var items = new[] + { new ComboBoxItem() { - Content = content = new Control() + Content = parentContent.Child } }; var target = new ComboBox @@ -425,14 +422,17 @@ namespace Avalonia.Controls.UnitTests var root = new TestRoot(target); target.ApplyTemplate(); - target.Presenter.ApplyTemplate(); target.SelectedIndex = 0; - // need help here how to connect 'content' to visual tree, or how to open popup - - var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; + Assert.Equal(FlowDirection.LeftToRight, rectangle.FlowDirection); + parentContent.FlowDirection = FlowDirection.RightToLeft; + + var popup = target.GetVisualDescendants().OfType().First(); + popup.PlacementTarget = new Window(); + popup.Open(); + Assert.Equal(FlowDirection.RightToLeft, rectangle.FlowDirection); } } From 5bf28b671d42b5682930e27014d5897fe90bda73 Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Tue, 31 May 2022 20:42:16 +0300 Subject: [PATCH 7/8] some fixes --- tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index 70b713d6d0..aa32af7e51 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -379,7 +379,6 @@ namespace Avalonia.Controls.UnitTests }; var target = new ComboBox { - FlowDirection = FlowDirection.RightToLeft, Items = items, Template = GetTemplate() }; @@ -392,7 +391,7 @@ namespace Avalonia.Controls.UnitTests Assert.Equal(FlowDirection.LeftToRight, rectangle.FlowDirection); parentContent.FlowDirection = FlowDirection.RightToLeft; - target.InvalidateMirrorTransform(); + target.FlowDirection = FlowDirection.RightToLeft; Assert.Equal(FlowDirection.RightToLeft, rectangle.FlowDirection); } From b6e66047f21cec797302c305b487b93881b7fa1c Mon Sep 17 00:00:00 2001 From: daniel mayost Date: Wed, 1 Jun 2022 13:54:50 +0300 Subject: [PATCH 8/8] add fixes --- src/Avalonia.Controls/ComboBox.cs | 11 ++++++----- .../FlowDirectionTests.cs | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index 5ba1195159..05be5ad00d 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -434,11 +434,12 @@ namespace Avalonia.Controls { if (SelectionBoxItem is Rectangle rectangle) { - var content = (rectangle.Fill as VisualBrush)!.Visual as Control; - var flowDirection = (((IVisual)content!).VisualParent as Control)?.FlowDirection ?? - FlowDirection.LeftToRight; - - rectangle.FlowDirection = flowDirection; + if ((rectangle.Fill as VisualBrush)?.Visual is Control content) + { + var flowDirection = (((IVisual)content!).VisualParent as Control)?.FlowDirection ?? + FlowDirection.LeftToRight; + rectangle.FlowDirection = flowDirection; + } } } diff --git a/tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs b/tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs index 6739eff638..6c43103ecb 100644 --- a/tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs +++ b/tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs @@ -17,7 +17,23 @@ namespace Avalonia.Controls.UnitTests } [Fact] - public void HasMirrorTransform_Of_Children_Is_Updated_After_Change() + public void HasMirrorTransform_Of_LTR_Children_Should_Be_True_For_RTL_Parent() + { + Control child; + var target = new Decorator + { + FlowDirection = FlowDirection.RightToLeft, + Child = child = new Control() + }; + + child.FlowDirection = FlowDirection.LeftToRight; + + Assert.True(target.HasMirrorTransform); + Assert.True(child.HasMirrorTransform); + } + + [Fact] + public void HasMirrorTransform_Of_Children_Is_Updated_After_Parent_Changeed() { Control child; var target = new Decorator