Explorar o código

Add SplitViewPanePlacement settings for Top and Bottom. (#19465)

* add SplitViewPanePlacement settings for Top and Bottom.

* remove duplicated styles.

* add missing transparent fills of lightdismiss area.

* add simple theme support for splitview pane placement top/bottom.
Dan Walmsley hai 1 mes
pai
achega
7f47605256

+ 8 - 1
samples/ControlCatalog/Pages/SplitViewPage.xaml

@@ -20,7 +20,13 @@
                       Content="UseLightDismissOverlayMode"
                       IsChecked="{Binding UseLightDismissOverlayMode, ElementName=SplitView}" />
 
-        <ToggleSwitch OffContent="Left" OnContent="Right" Content="Placement" IsChecked="{Binding !IsLeft}" />
+        <ComboBox Name="Placement" Width="170" Margin="10" SelectedIndex="{Binding Placement}">
+          <ComboBoxItem>Left</ComboBoxItem>
+          <ComboBoxItem>Right</ComboBoxItem>
+          <ComboBoxItem>Top</ComboBoxItem>
+          <ComboBoxItem>Bottom</ComboBoxItem>
+        </ComboBox>
+        
 
         <TextBlock Text="DisplayMode" />
         <ComboBox Name="DisplayModeSelector" Width="170" Margin="10" SelectedIndex="{Binding DisplayMode}">
@@ -52,6 +58,7 @@
             BorderThickness="1">
         <!--{Binding SelectedItem.Tag, ElementName=PaneBackgroundSelector}-->
         <SplitView Name="SplitView"
+                      
                       PanePlacement="{Binding PanePlacement}"
                       PaneBackground="{Binding ((Control)SelectedItem).Tag, ElementName=PaneBackgroundSelector, FallbackValue={x:Null}}"
                       OpenPaneLength="{Binding Value, ElementName=OpenPaneLengthSlider}"

+ 13 - 5
samples/ControlCatalog/ViewModels/SplitViewPageViewModel.cs

@@ -6,15 +6,15 @@ namespace ControlCatalog.ViewModels
 {
     public class SplitViewPageViewModel : ViewModelBase
     {
-        private bool _isLeft = true;
         private int _displayMode = 3; //CompactOverlay
+        private int _placement = 0; //Left
 
-        public bool IsLeft
+        public int Placement
         {
-            get => _isLeft;
+            get => _placement;
             set
             {
-                this.RaiseAndSetIfChanged(ref _isLeft, value);
+                this.RaiseAndSetIfChanged(ref _placement, value);
                 this.RaisePropertyChanged(nameof(PanePlacement));
             }
         }
@@ -29,7 +29,15 @@ namespace ControlCatalog.ViewModels
             }
         }
 
-        public SplitViewPanePlacement PanePlacement => _isLeft ? SplitViewPanePlacement.Left : SplitViewPanePlacement.Right;
+        public SplitViewPanePlacement PanePlacement =>
+            _placement switch
+            {
+                0 => SplitViewPanePlacement.Left,
+                1 => SplitViewPanePlacement.Right,
+                2 => SplitViewPanePlacement.Top,
+                3 => SplitViewPanePlacement.Bottom,
+                _ => SplitViewPanePlacement.Left
+            };
         
         public SplitViewDisplayMode CurrentDisplayMode
         {

+ 21 - 3
src/Avalonia.Controls/SplitView/SplitView.cs

@@ -18,7 +18,7 @@ namespace Avalonia.Controls
     [TemplatePart("PART_PaneRoot", typeof(Panel))]
     [PseudoClasses(pcOpen, pcClosed)]
     [PseudoClasses(pcCompactOverlay, pcCompactInline, pcOverlay, pcInline)]
-    [PseudoClasses(pcLeft, pcRight)]
+    [PseudoClasses(pcLeft, pcRight, pcTop, pcBottom)]
     [PseudoClasses(pcLightDismiss)]
     public class SplitView : ContentControl
     {
@@ -30,6 +30,8 @@ namespace Avalonia.Controls
         private const string pcInline = ":inline";
         private const string pcLeft = ":left";
         private const string pcRight = ":right";
+        private const string pcTop = ":top";
+        private const string pcBottom = ":bottom";
         private const string pcLightDismiss = ":lightDismiss";
 
         /// <summary>
@@ -464,6 +466,8 @@ namespace Avalonia.Controls
             {
                 SplitViewPanePlacement.Left => pcLeft,
                 SplitViewPanePlacement.Right => pcRight,
+                SplitViewPanePlacement.Top => pcTop,
+                SplitViewPanePlacement.Bottom => pcBottom,
                 _ => throw new ArgumentOutOfRangeException(nameof(placement), placement, null)
             };
         }
@@ -501,11 +505,14 @@ namespace Avalonia.Controls
             if (displayMode == SplitViewDisplayMode.CompactInline)
             {
                 TemplateSettings.ClosedPaneWidth = newLen;
+                TemplateSettings.ClosedPaneHeight = newLen;
             }
             else if (displayMode == SplitViewDisplayMode.CompactOverlay)
             {
                 TemplateSettings.ClosedPaneWidth = newLen;
                 TemplateSettings.PaneColumnGridLength = new GridLength(newLen, GridUnitType.Pixel);
+                TemplateSettings.ClosedPaneHeight = newLen;
+                TemplateSettings.PaneRowGridLength = new GridLength(newLen, GridUnitType.Pixel);
             }
         }
 
@@ -521,14 +528,25 @@ namespace Avalonia.Controls
 
             var (closedPaneWidth, paneColumnGridLength) = newValue switch
             {
-                SplitViewDisplayMode.Overlay => (0, new GridLength(0, GridUnitType.Pixel)),
+                SplitViewDisplayMode.Overlay => (0d, new GridLength(0, GridUnitType.Pixel)),
                 SplitViewDisplayMode.CompactOverlay => (CompactPaneLength, new GridLength(CompactPaneLength, GridUnitType.Pixel)),
-                SplitViewDisplayMode.Inline => (0, new GridLength(0, GridUnitType.Auto)),
+                SplitViewDisplayMode.Inline => (0d, new GridLength(0, GridUnitType.Auto)),
                 SplitViewDisplayMode.CompactInline => (CompactPaneLength, new GridLength(0, GridUnitType.Auto)),
                 _ => throw new NotImplementedException(),
             };
             TemplateSettings.ClosedPaneWidth = closedPaneWidth;
             TemplateSettings.PaneColumnGridLength = paneColumnGridLength;
+
+            var (closedPaneHeight, paneRowGridLength) = newValue switch
+            {
+                SplitViewDisplayMode.Overlay => (0d, new GridLength(0, GridUnitType.Pixel)),
+                SplitViewDisplayMode.CompactOverlay => (CompactPaneLength, new GridLength(CompactPaneLength, GridUnitType.Pixel)),
+                SplitViewDisplayMode.Inline => (0d, new GridLength(0, GridUnitType.Auto)),
+                SplitViewDisplayMode.CompactInline => (CompactPaneLength, new GridLength(0, GridUnitType.Auto)),
+                _ => throw new NotImplementedException(),
+            };
+            TemplateSettings.ClosedPaneHeight = closedPaneHeight;
+            TemplateSettings.PaneRowGridLength = paneRowGridLength;
             
             InvalidateLightDismissSubscription();
         }

+ 11 - 1
src/Avalonia.Controls/SplitView/SplitViewPanePlacement.cs

@@ -13,6 +13,16 @@
         /// <summary>
         /// The pane is shown to the right of content.
         /// </summary>
-        Right
+        Right,
+
+        /// <summary>
+        /// The pane is shown above the content.
+        /// </summary>
+        Top,
+
+        /// <summary>
+        /// The pane is shown below the content.
+        /// </summary>
+        Bottom
     }
 }

+ 23 - 0
src/Avalonia.Controls/SplitView/SplitViewTemplateSettings.cs

@@ -19,6 +19,15 @@
             AvaloniaProperty.Register<SplitViewTemplateSettings, GridLength>(
                 nameof(PaneColumnGridLength));
 
+        public static readonly StyledProperty<double> ClosedPaneHeightProperty =
+            AvaloniaProperty.Register<SplitViewTemplateSettings,
+                double>(nameof(ClosedPaneHeight),
+                0d);
+
+        public static readonly StyledProperty<GridLength> PaneRowGridLengthProperty =
+            AvaloniaProperty.Register<SplitViewTemplateSettings, GridLength>(
+                nameof(PaneRowGridLength));
+
         [System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1032", Justification = "This property is supposed to be a styled readonly property.")]
         public double ClosedPaneWidth
         {
@@ -32,5 +41,19 @@
             get => GetValue(PaneColumnGridLengthProperty);
             internal set => SetValue(PaneColumnGridLengthProperty, value);
         }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1032", Justification = "This property is supposed to be a styled readonly property.")]
+        public double ClosedPaneHeight
+        {
+            get => GetValue(ClosedPaneHeightProperty);
+            internal set => SetValue(ClosedPaneHeightProperty, value);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1032", Justification = "This property is supposed to be a styled readonly property.")]
+        public GridLength PaneRowGridLength
+        {
+            get => GetValue(PaneRowGridLengthProperty);
+            internal set => SetValue(PaneRowGridLengthProperty, value);
+        }
     }
 }

+ 245 - 39
src/Avalonia.Themes.Fluent/Controls/SplitView.xaml

@@ -51,7 +51,7 @@
                          HorizontalAlignment="Right"  />
             </Panel>
 
-            <Panel Name="ContentRoot">
+            <Panel Name="ContentRoot" Grid.Column="1">
               <ContentPresenter x:Name="PART_ContentPresenter"
                                 Content="{TemplateBinding Content}"
                                 ContentTemplate="{TemplateBinding ContentTemplate}" />
@@ -135,11 +135,11 @@
                          Width="1" HorizontalAlignment="Left"  />
             </Panel>
 
-            <Panel Name="ContentRoot">
+            <Panel Name="ContentRoot" Grid.Column="0">
               <ContentPresenter x:Name="PART_ContentPresenter"
                                 Content="{TemplateBinding Content}"
                                 ContentTemplate="{TemplateBinding ContentTemplate}" />
-              <Rectangle Name="LightDismissLayer" IsVisible="False"/>
+              <Rectangle Name="LightDismissLayer" Fill="Transparent" IsVisible="False"/>
             </Panel>
 
           </Grid>
@@ -195,48 +195,254 @@
       </Style>
     </Style>
 
-    <Style Selector="^:open">
-      <Style Selector="^ /template/ Panel#PART_PaneRoot">
-        <Setter Property="Transitions">
-          <Transitions>
-            <DoubleTransition Property="Width"
-                              Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
-                              Easing="{StaticResource SplitViewPaneAnimationEasing}" />
-          </Transitions>
-        </Setter>
-        <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
-      </Style>
-      <Style Selector="^ /template/ Rectangle#LightDismissLayer">
-        <Setter Property="Transitions">
-          <Transitions>
-            <DoubleTransition Property="Opacity"
-                              Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
-                              Easing="{StaticResource SplitViewPaneAnimationEasing}" />
-          </Transitions>
-        </Setter>
-        <Setter Property="Opacity" Value="1.0"/>
+    <!-- TOP placement -->
+    <Style Selector="^:top">
+      <Setter Property="Template">
+        <ControlTemplate>
+          <Grid Name="Container" Background="{TemplateBinding Background}">
+            <Grid.RowDefinitions>
+              <RowDefinition Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PaneRowGridLength}"/>
+              <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+
+            <Panel Name="PART_PaneRoot"
+                   Background="{TemplateBinding PaneBackground}"
+                   ClipToBounds="True"
+                   VerticalAlignment="Top"
+                   ZIndex="100">
+              <ContentPresenter x:Name="PART_PanePresenter"
+                                Content="{TemplateBinding Pane}"
+                                ContentTemplate="{TemplateBinding PaneTemplate}" />
+              <Rectangle Name="HCPaneBorder"
+                         Fill="{DynamicResource SystemControlForegroundTransparentBrush}"
+                         Height="1"
+                         VerticalAlignment="Bottom"  />
+            </Panel>
+
+            <Panel Name="ContentRoot" Grid.Row="1">
+              <ContentPresenter x:Name="PART_ContentPresenter"
+                                Content="{TemplateBinding Content}"
+                                ContentTemplate="{TemplateBinding ContentTemplate}" />
+              <Rectangle Name="LightDismissLayer"
+                         Fill="Transparent"
+                         IsVisible="False"/>
+            </Panel>
+
+          </Grid>
+        </ControlTemplate>
+      </Setter>
+
+      <Style Selector="^:overlay">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+          <Setter Property="Grid.RowSpan" Value="1"/>
+          <Setter Property="Grid.Row" Value="0"/>
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="1"/>
+          <Setter Property="Grid.RowSpan" Value="2"/>
+        </Style>
+      </Style>
+
+      <Style Selector="^:compactinline">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Grid.RowSpan" Value="1"/>
+          <Setter Property="Grid.Row" Value="0"/>
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="1"/>
+          <Setter Property="Grid.RowSpan" Value="1"/>
+        </Style>
+      </Style>
+
+      <Style Selector="^:compactoverlay">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Grid.RowSpan" Value="1"/>
+          <Setter Property="Grid.Row" Value="0"/>
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="1"/>
+          <Setter Property="Grid.RowSpan" Value="1"/>
+        </Style>
+      </Style>
+
+      <Style Selector="^:inline">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Grid.RowSpan" Value="1"/>
+          <Setter Property="Grid.Row" Value="0"/>
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="1"/>
+          <Setter Property="Grid.RowSpan" Value="1"/>
+        </Style>
       </Style>
     </Style>
 
-    <Style Selector="^:closed">
-      <Style Selector="^ /template/ Panel#PART_PaneRoot">
-        <Setter Property="Transitions">
-          <Transitions>
-            <DoubleTransition Property="Width" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" Easing="{StaticResource SplitViewPaneAnimationEasing}" />
-          </Transitions>
-        </Setter>
-        <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneWidth}" />
-      </Style>
-      <Style Selector="^ /template/ Rectangle#LightDismissLayer">
-        <Setter Property="Transitions">
-          <Transitions>
-            <DoubleTransition Property="Opacity" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" Easing="{StaticResource SplitViewPaneAnimationEasing}" />
-          </Transitions>
-        </Setter>
-        <Setter Property="Opacity" Value="0.0"/>
+    <!-- BOTTOM placement -->
+    <Style Selector="^:bottom">
+      <Setter Property="Template">
+        <ControlTemplate>
+          <Grid Name="Container" Background="{TemplateBinding Background}">
+            <Grid.RowDefinitions>
+              <RowDefinition Height="*"/>
+              <RowDefinition Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PaneRowGridLength}"/>
+            </Grid.RowDefinitions>
+
+            <Panel Name="PART_PaneRoot" Background="{TemplateBinding PaneBackground}"
+                   ClipToBounds="True"
+                   VerticalAlignment="Bottom"
+                   ZIndex="100">
+              <ContentPresenter x:Name="PART_PanePresenter"
+                                Content="{TemplateBinding Pane}"
+                                ContentTemplate="{TemplateBinding PaneTemplate}"/>
+              <Rectangle Name="HCPaneBorder"
+                         Fill="{DynamicResource SystemControlForegroundTransparentBrush}"
+                         Height="1" VerticalAlignment="Top"  />
+            </Panel>
+
+            <Panel Name="ContentRoot" Grid.Row="0">
+              <ContentPresenter x:Name="PART_ContentPresenter"
+                                Content="{TemplateBinding Content}"
+                                ContentTemplate="{TemplateBinding ContentTemplate}" />
+              <Rectangle Name="LightDismissLayer" Fill="Transparent" IsVisible="False"/>
+            </Panel>
+
+          </Grid>
+        </ControlTemplate>
+      </Setter>
+
+      <Style Selector="^:overlay">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+          <Setter Property="Grid.RowSpan" Value="2"/>
+          <Setter Property="Grid.Row" Value="1"/>
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="0"/>
+          <Setter Property="Grid.RowSpan" Value="2"/>
+        </Style>
+      </Style>
+
+      <Style Selector="^:compactinline">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Grid.RowSpan" Value="1"/>
+          <Setter Property="Grid.Row" Value="1"/>
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="0"/>
+          <Setter Property="Grid.RowSpan" Value="1"/>
+        </Style>
+      </Style>
+
+      <Style Selector="^:compactoverlay">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Grid.RowSpan" Value="2"/>
+          <Setter Property="Grid.Row" Value="1"/>
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="0"/>
+          <Setter Property="Grid.RowSpan" Value="1"/>
+        </Style>
+      </Style>
+
+      <Style Selector="^:inline">
+        <Style Selector="^ /template/ Panel#PART_PaneRoot">
+          <Setter Property="Grid.RowSpan" Value="1"/>
+          <Setter Property="Grid.Row" Value="1"/>
+          <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+        </Style>
+        <Style Selector="^ /template/ Panel#ContentRoot">
+          <Setter Property="Grid.Row" Value="0"/>
+          <Setter Property="Grid.RowSpan" Value="1"/>
+        </Style>
       </Style>
     </Style>
 
+    <!-- Placement-specific open/closed transitions for horizontal panes (left/right) -->
+    <Style Selector="^:left:open /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Width"
+                            Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
+    </Style>
+    <Style Selector="^:right:open /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Width"
+                            Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
+    </Style>
+
+    <Style Selector="^:left:closed /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Width" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneWidth}" />
+    </Style>
+    <Style Selector="^:right:closed /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Width" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneWidth}" />
+    </Style>
+
+    <!-- Placement-specific open/closed transitions for vertical panes (top/bottom) -->
+    <Style Selector="^:top:open /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Height"
+                            Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
+    </Style>
+
+    <Style Selector="^:bottom:open /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Height"
+                            Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
+    </Style>
+
+    <Style Selector="^:top:closed /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Height" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+
+    <Style Selector="^:bottom:closed /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Height" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}" Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+
     <Style Selector="^:lightDismiss /template/ Rectangle#LightDismissLayer">
       <Setter Property="Fill" Value="{DynamicResource SplitViewLightDismissOverlayBackground}" />
     </Style>

+ 219 - 10
src/Avalonia.Themes.Simple/Controls/SplitView.xaml

@@ -52,7 +52,7 @@
                          HorizontalAlignment="Right" />
             </Panel>
 
-            <Panel Name="ContentRoot">
+            <Panel Name="ContentRoot" Grid.Column="1">
               <ContentPresenter x:Name="PART_ContentPresenter" Content="{TemplateBinding Content}"
                                 ContentTemplate="{TemplateBinding ContentTemplate}" />
               <Rectangle Name="LightDismissLayer" IsVisible="False"/>
@@ -135,7 +135,7 @@
                          Width="1" HorizontalAlignment="Left" />
             </Panel>
 
-            <Panel Name="ContentRoot">
+            <Panel Name="ContentRoot" Grid.Column="0">
               <ContentPresenter x:Name="PART_ContentPresenter" Content="{TemplateBinding Content}"
                                 ContentTemplate="{TemplateBinding ContentTemplate}" />
               <Rectangle Name="LightDismissLayer" IsVisible="False"/>
@@ -194,8 +194,175 @@
       <Setter Property="Grid.ColumnSpan" Value="1" />
     </Style>
 
+    <!-- TOP placement -->
+    <Style Selector="^:top">
+      <Setter Property="Template">
+        <ControlTemplate TargetType="SplitView">
+          <Grid Name="Container" Background="{TemplateBinding Background}">
+            <Grid.RowDefinitions>
+              <RowDefinition Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PaneRowGridLength}" />
+              <RowDefinition Height="*" />
+            </Grid.RowDefinitions>
+
+            <Panel Name="PART_PaneRoot"
+                   Background="{TemplateBinding PaneBackground}"
+                   ClipToBounds="True"
+                   VerticalAlignment="Top"
+                   ZIndex="100">
+              <ContentPresenter x:Name="PART_PanePresenter"
+                                Content="{TemplateBinding Pane}"
+                                ContentTemplate="{TemplateBinding PaneTemplate}" />
+              <Rectangle Name="HCPaneBorder"
+                         Fill="Transparent"
+                         Height="1"
+                         VerticalAlignment="Bottom" />
+            </Panel>
+
+            <Panel Name="ContentRoot" Grid.Row="1">
+              <ContentPresenter x:Name="PART_ContentPresenter"
+                                Content="{TemplateBinding Content}"
+                                ContentTemplate="{TemplateBinding ContentTemplate}" />
+              <Rectangle Name="LightDismissLayer" IsVisible="False" />
+            </Panel>
+          </Grid>
+        </ControlTemplate>
+      </Setter>
+    </Style>
+
+    <!-- Overlay -->
+    <Style Selector="^:overlay:top /template/ Panel#PART_PaneRoot">
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+      <Setter Property="Grid.RowSpan" Value="1" />
+      <Setter Property="Grid.Row" Value="0" />
+    </Style>
+    <Style Selector="^:overlay:top /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="1" />
+      <Setter Property="Grid.RowSpan" Value="2" />
+    </Style>
+
+    <!-- CompactInline -->
+    <Style Selector="^:compactinline:top /template/ Panel#PART_PaneRoot">
+      <Setter Property="Grid.RowSpan" Value="1" />
+      <Setter Property="Grid.Row" Value="0" />
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+    <Style Selector="^:compactinline:top /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="1" />
+      <Setter Property="Grid.RowSpan" Value="1" />
+    </Style>
+
+    <!-- CompactOverlay -->
+    <Style Selector="^:compactoverlay:top /template/ Panel#PART_PaneRoot">
+      <Setter Property="Grid.RowSpan" Value="1" />
+      <Setter Property="Grid.Row" Value="0" />
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+    <Style Selector="^:compactoverlay:top /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="1" />
+      <Setter Property="Grid.RowSpan" Value="1" />
+    </Style>
+
+    <!-- Inline -->
+    <Style Selector="^:inline:top /template/ Panel#PART_PaneRoot">
+      <Setter Property="Grid.RowSpan" Value="1" />
+      <Setter Property="Grid.Row" Value="0" />
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+    <Style Selector="^:inline:top /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="1" />
+      <Setter Property="Grid.RowSpan" Value="1" />
+    </Style>
+
+    <!-- BOTTOM placement -->
+    <Style Selector="^:bottom">
+      <Setter Property="Template">
+        <ControlTemplate TargetType="SplitView">
+          <Grid Name="Container" Background="{TemplateBinding Background}">
+            <Grid.RowDefinitions>
+              <RowDefinition Height="*" />
+              <RowDefinition Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.PaneRowGridLength}" />
+            </Grid.RowDefinitions>
+
+            <Panel Name="PART_PaneRoot"
+                   Background="{TemplateBinding PaneBackground}"
+                   ClipToBounds="True"
+                   VerticalAlignment="Bottom"
+                   ZIndex="100">
+              <ContentPresenter x:Name="PART_PanePresenter"
+                                Content="{TemplateBinding Pane}"
+                                ContentTemplate="{TemplateBinding PaneTemplate}" />
+              <Rectangle Name="HCPaneBorder"
+                         Fill="Transparent"
+                         Height="1"
+                         VerticalAlignment="Top" />
+            </Panel>
+
+            <Panel Name="ContentRoot" Grid.Row="0">
+              <ContentPresenter x:Name="PART_ContentPresenter"
+                                Content="{TemplateBinding Content}"
+                                ContentTemplate="{TemplateBinding ContentTemplate}" />
+              <Rectangle Name="LightDismissLayer" IsVisible="False" />
+            </Panel>
+          </Grid>
+        </ControlTemplate>
+      </Setter>
+    </Style>
+
+    <!-- Overlay -->
+    <Style Selector="^:overlay:bottom /template/ Panel#PART_PaneRoot">
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+      <Setter Property="Grid.RowSpan" Value="2" />
+      <Setter Property="Grid.Row" Value="1" />
+    </Style>
+    <Style Selector="^:overlay:bottom /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="0" />
+      <Setter Property="Grid.RowSpan" Value="2" />
+    </Style>
+
+    <!-- CompactInline -->
+    <Style Selector="^:compactinline:bottom /template/ Panel#PART_PaneRoot">
+      <Setter Property="Grid.RowSpan" Value="1" />
+      <Setter Property="Grid.Row" Value="1" />
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+    <Style Selector="^:compactinline:bottom /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="0" />
+      <Setter Property="Grid.RowSpan" Value="1" />
+    </Style>
+
+    <!-- CompactOverlay -->
+    <Style Selector="^:compactoverlay:bottom /template/ Panel#PART_PaneRoot">
+      <Setter Property="Grid.RowSpan" Value="2" />
+      <Setter Property="Grid.Row" Value="1" />
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+    <Style Selector="^:compactoverlay:bottom /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="0" />
+      <Setter Property="Grid.RowSpan" Value="1" />
+    </Style>
+
+    <!-- Inline -->
+    <Style Selector="^:inline:bottom /template/ Panel#PART_PaneRoot">
+      <Setter Property="Grid.RowSpan" Value="1" />
+      <Setter Property="Grid.Row" Value="1" />
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+    <Style Selector="^:inline:bottom /template/ Panel#ContentRoot">
+      <Setter Property="Grid.Row" Value="0" />
+      <Setter Property="Grid.RowSpan" Value="1" />
+    </Style>
+
     <!-- Open/Close Pane animation  -->
-    <Style Selector="^:open /template/ Panel#PART_PaneRoot">
+    <!-- Scope width animations to horizontal placements -->
+    <Style Selector="^:left:open /template/ Panel#PART_PaneRoot">
       <Setter Property="Transitions">
         <Transitions>
           <DoubleTransition Property="Width" Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
@@ -204,17 +371,17 @@
       </Setter>
       <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
     </Style>
-    <Style Selector="^:open /template/ Rectangle#LightDismissLayer">
+    <Style Selector="^:right:open /template/ Panel#PART_PaneRoot">
       <Setter Property="Transitions">
         <Transitions>
-          <DoubleTransition Property="Opacity" Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
+          <DoubleTransition Property="Width" Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
                             Easing="{StaticResource SplitViewPaneAnimationEasing}" />
         </Transitions>
       </Setter>
-      <Setter Property="Opacity" Value="1.0" />
+      <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
     </Style>
 
-    <Style Selector="^:closed /template/ Panel#PART_PaneRoot">
+    <Style Selector="^:left:closed /template/ Panel#PART_PaneRoot">
       <Setter Property="Transitions">
         <Transitions>
           <DoubleTransition Property="Width" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}"
@@ -224,14 +391,56 @@
       <Setter Property="Width"
               Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneWidth}" />
     </Style>
-    <Style Selector="^:closed /template/ Rectangle#LightDismissLayer">
+    <Style Selector="^:right:closed /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Width" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Width"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneWidth}" />
+    </Style>
+
+    <!-- Placement-specific open/closed transitions for vertical panes (top/bottom) -->
+    <Style Selector="^:top:open /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Height" Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
+    </Style>
+    <Style Selector="^:bottom:open /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Height" Duration="{StaticResource SplitViewPaneAnimationOpenDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=OpenPaneLength}" />
+    </Style>
+
+    <Style Selector="^:top:closed /template/ Panel#PART_PaneRoot">
+      <Setter Property="Transitions">
+        <Transitions>
+          <DoubleTransition Property="Height" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}"
+                            Easing="{StaticResource SplitViewPaneAnimationEasing}" />
+        </Transitions>
+      </Setter>
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
+    </Style>
+    <Style Selector="^:bottom:closed /template/ Panel#PART_PaneRoot">
       <Setter Property="Transitions">
         <Transitions>
-          <DoubleTransition Property="Opacity" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}"
+          <DoubleTransition Property="Height" Duration="{StaticResource SplitViewPaneAnimationCloseDuration}"
                             Easing="{StaticResource SplitViewPaneAnimationEasing}" />
         </Transitions>
       </Setter>
-      <Setter Property="Opacity" Value="0.0" />
+      <Setter Property="Height"
+              Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ClosedPaneHeight}" />
     </Style>
 
     <Style Selector="^ /template/ Rectangle#LightDismissLayer">