Browse Source

Fix: TabItem.TabStripPlacement is not set for new tab items (#13849)

* TabItem.TabStripPlacemenet should be correctly set

* fix: TabItem.TabStripPlacemenet should be correctly set

* move TabItemStripPlacement assignment to PrepareContainerForItemOverride
* remove excessive UpdateTabStripPlacement call on TabStripPlacementProperty.Changed
pavelovcharov 1 year ago
parent
commit
602dc2850f

+ 6 - 2
src/Avalonia.Controls/TabControl.cs

@@ -73,7 +73,6 @@ namespace Avalonia.Controls
         {
             SelectionModeProperty.OverrideDefaultValue<TabControl>(SelectionMode.AlwaysSelected);
             ItemsPanelProperty.OverrideDefaultValue<TabControl>(DefaultPanel);
-            TabStripPlacementProperty.Changed.AddClassHandler<TabControl>((x, e) => x.UpdateTabStripPlacement());
             AffectsMeasure<TabControl>(TabStripPlacementProperty);
             SelectedItemProperty.Changed.AddClassHandler<TabControl>((x, e) => x.UpdateSelectedContent());
             AutomationProperties.ControlTypeOverrideProperty.OverrideDefaultValue<TabControl>(AutomationControlType.Tab);
@@ -154,7 +153,7 @@ namespace Avalonia.Controls
 
         protected internal override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
         {
-            return new TabItem { TabStripPlacement = TabStripPlacement };
+            return new TabItem();
         }
 
         protected internal override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
@@ -166,6 +165,11 @@ namespace Avalonia.Controls
         {
             base.PrepareContainerForItemOverride(element, item, index);
 
+            if (element is TabItem tabItem)
+            {
+                tabItem.TabStripPlacement = TabStripPlacement;
+            }
+            
             if (index == SelectedIndex)
             {
                 UpdateSelectedContent(element);

+ 77 - 0
tests/Avalonia.Controls.UnitTests/TabControlTests.cs

@@ -572,6 +572,83 @@ namespace Avalonia.Controls.UnitTests
             Assert.Equal("Header from style", tabItem.Header);
         }
 
+        [Fact]
+        public void TabItem_TabStripPlacement_Should_Be_Correctly_Set()
+        {
+            var items = new object[]
+            {
+                "Foo",
+                new TabItem { Content = new TextBlock { Text = "Baz" } }
+            };
+
+            var target = new TabControl
+            {
+                Template = TabControlTemplate(),
+                DataContext = "Base",
+                ItemsSource = items
+            };
+
+            ApplyTemplate(target);
+
+            var result = target.GetLogicalChildren()
+                .OfType<TabItem>()
+                .ToList();
+            Assert.Collection(
+                result,
+                x => Assert.Equal(Dock.Top, x.TabStripPlacement),
+                x => Assert.Equal(Dock.Top, x.TabStripPlacement)
+            );
+
+            target.TabStripPlacement = Dock.Right;
+            result = target.GetLogicalChildren()
+                .OfType<TabItem>()
+                .ToList();
+            Assert.Collection(
+                result,
+                x => Assert.Equal(Dock.Right, x.TabStripPlacement),
+                x => Assert.Equal(Dock.Right, x.TabStripPlacement)
+            );
+        }
+        
+        [Fact]
+        public void TabItem_TabStripPlacement_Should_Be_Correctly_Set_For_New_Items()
+        {
+            var items = new object[]
+            {
+                "Foo",
+                new TabItem { Content = new TextBlock { Text = "Baz" } }
+            };
+
+            var target = new TabControl
+            {
+                Template = TabControlTemplate(),
+                DataContext = "Base"
+            };
+
+            ApplyTemplate(target);
+
+            target.ItemsSource = items;
+            
+            var result = target.GetLogicalChildren()
+                .OfType<TabItem>()
+                .ToList();
+            Assert.Collection(
+                result,
+                x => Assert.Equal(Dock.Top, x.TabStripPlacement),
+                x => Assert.Equal(Dock.Top, x.TabStripPlacement)
+            );
+
+            target.TabStripPlacement = Dock.Right;
+            result = target.GetLogicalChildren()
+                .OfType<TabItem>()
+                .ToList();
+            Assert.Collection(
+                result,
+                x => Assert.Equal(Dock.Right, x.TabStripPlacement),
+                x => Assert.Equal(Dock.Right, x.TabStripPlacement)
+            );
+        }
+        
         private static IControlTemplate TabControlTemplate()
         {
             return new FuncControlTemplate<TabControl>((parent, scope) =>