Repository: AvaloniaUI/Avalonia

Issue:
SplitView ":open"/":closed" pseudoclasses aren't set on control initialization
### Describe the bug

SplitView control after it initialized does not have `:open` or `:closed` pseudoclass set. Regardless of the value in the `IsPaneOpen` property. 


### To Reproduce

Create Window with a SplitView control, set IsPaneOpen to any value (e.g, by binding to ViewModel)
Run the application in Debug, open Debug tools
In Logical Tree, find SplitView. The SplitView doesn't have `:open` / `:closed` pseudoclass set regardless of the value in the `IsPaneOpen` property. 
![image](https://github.com/user-attachments/assets/1a26583e-303c-428b-8bca-3e2ab323dfaa)

Pseudoclass is set only after first change of `IsPaneOpen` property

### Expected behavior

SplitView control after initialization should have `:open` / `:closed` pseudoclass set depending of the value in the `IsPaneOpen` property

### Avalonia version

11.1.0

### OS

Windows

### Additional context

After looking into `SplitView.cs` source code, the problem appears to be that the logic for changing pseudoclass based on `IsPaneOpen` value is present only in `OnPropertyChanged` method. Adding same logic to constructor should fix the issue
SplitView ":open"/":closed" pseudoclasses aren't set on control initialization
### Describe the bug

SplitView control after it initialized does not have `:open` or `:closed` pseudoclass set. Regardless of the value in the `IsPaneOpen` property. 


### To Reproduce

Create Window with a SplitView control, set IsPaneOpen to any value (e.g, by binding to ViewModel)
Run the application in Debug, open Debug tools
In Logical Tree, find SplitView. The SplitView doesn't have `:open` / `:closed` pseudoclass set regardless of the value in the `IsPaneOpen` property. 
![image](https://github.com/user-attachments/assets/1a26583e-303c-428b-8bca-3e2ab323dfaa)

Pseudoclass is set only after first change of `IsPaneOpen` property

### Expected behavior

SplitView control after initialization should have `:open` / `:closed` pseudoclass set depending of the value in the `IsPaneOpen` property

### Avalonia version

11.1.0

### OS

Windows

### Additional context

After looking into `SplitView.cs` source code, the problem appears to be that the logic for changing pseudoclass based on `IsPaneOpen` value is present only in `OnPropertyChanged` method. Adding same logic to constructor should fix the issue


Hints:
@OccVeneficus if you have an idea how to solve it, a PR is welcome. 
@OccVeneficus if you have an idea how to solve it, a PR is welcome. 

Patch:
diff --git a/src/Avalonia.Controls/SplitView/SplitView.cs b/src/Avalonia.Controls/SplitView/SplitView.cs
index fed0367d122..fd6fd98de69 100644
--- a/src/Avalonia.Controls/SplitView/SplitView.cs
+++ b/src/Avalonia.Controls/SplitView/SplitView.cs
@@ -297,6 +297,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
             _pane = e.NameScope.Find<Panel>("PART_PaneRoot");
 
             UpdateVisualStateForDisplayMode(DisplayMode);
+            UpdatePaneStatePseudoClass(IsPaneOpen);
         }
 
         protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
@@ -331,19 +332,13 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
             else if (change.Property == IsPaneOpenProperty)
             {
                 bool isPaneOpen = change.GetNewValue<bool>();
-
+                UpdatePaneStatePseudoClass(isPaneOpen);
                 if (isPaneOpen)
                 {
-                    PseudoClasses.Add(pcOpen);
-                    PseudoClasses.Remove(pcClosed);
-
                     OnPaneOpened(new RoutedEventArgs(PaneOpenedEvent, this));
                 }
                 else
                 {
-                    PseudoClasses.Add(pcClosed);
-                    PseudoClasses.Remove(pcOpen);
-
                     OnPaneClosed(new RoutedEventArgs(PaneClosedEvent, this));
                 }
             }
@@ -579,6 +574,20 @@ private void TopLevelBackRequested(object? sender, RoutedEventArgs e)
             e.Handled = true;
         }
 
+        private void UpdatePaneStatePseudoClass(bool isPaneOpen)
+        {
+            if (isPaneOpen)
+            {
+                PseudoClasses.Add(pcOpen);
+                PseudoClasses.Remove(pcClosed);
+            }
+            else
+            {
+                PseudoClasses.Add(pcClosed);
+                PseudoClasses.Remove(pcOpen);
+            }
+        }
+
         /// <summary>
         /// Coerces/validates the <see cref="IsPaneOpen"/> property value.
         /// </summary>


Test patch:
diff --git a/tests/Avalonia.Controls.UnitTests/SplitViewTests.cs b/tests/Avalonia.Controls.UnitTests/SplitViewTests.cs
index 9b43c469ba2..47383fa9ad9 100644
--- a/tests/Avalonia.Controls.UnitTests/SplitViewTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/SplitViewTests.cs
@@ -1,5 +1,7 @@
-﻿using Avalonia.Input;
+﻿using Avalonia.Animation;
+using Avalonia.Input;
 using Avalonia.UnitTests;
+using Moq;
 using Xunit;
 
 namespace Avalonia.Controls.UnitTests
@@ -65,7 +67,8 @@ public void SplitView_Cancel_Close_Should_Prevent_Pane_From_Closing()
         [Fact]
         public void SplitView_TemplateSettings_Are_Correct_For_Display_Modes()
         {
-            using var app = UnitTestApplication.Start(TestServices.StyledWindow);
+            using var app = UnitTestApplication.Start(TestServices.StyledWindow
+                .With(globalClock: new MockGlobalClock()));
             var wnd = new Window
             {
                 Width = 1280,
@@ -280,5 +283,25 @@ public void Top_Level_Back_Requested_Closes_Light_Dismissable_Pane()
 
             Assert.True(splitView.IsPaneOpen);
         }
+
+        [Fact]
+        public void With_Default_IsPaneOpen_Value_Should_Have_Closed_Pseudo_Class_Set()
+        {
+            // Testing this control Pseudo Classes requires placing the SplitView on a window
+            // prior to asserting them, because some of the pseudo classes are set either when
+            // the template is applied or the control is attached to the visual tree
+            using var app = UnitTestApplication.Start(TestServices.StyledWindow
+                .With(globalClock: new MockGlobalClock()));
+            var wnd = new Window
+            {
+                Width = 1280,
+                Height = 720
+            };
+            var splitView = new SplitView();
+            wnd.Content = splitView;
+            wnd.Show();
+
+            Assert.Contains(splitView.Classes, ":closed".Equals);
+        }
     }
 }