WinUI 3: ToggleSwitch Height and internal padding sizing

John Granatino 25 Reputation points
2023-12-21T18:08:29.66+00:00

I have been having issues resizing the WinUI 3 Toggleswitch.

Changing the height & minheight to anything too small makes the internal content off center (and cut off). There's no way to vertically align the content to top or center. There's no way to change the internal padding or margins.

It seems to add a bunch of internal padding.

Putting it in a ViewBox makes it teeny-tiny which is not viable.

<Grid HorizontalAlignment="Center" VerticalAlignment="Center">     <StackPanel Orientation="Horizontal" Background="Gray">         <ToggleSwitch OnContent="ON" OffContent="OFF" Margin="3" Background="Green" MinWidth="0" MinHeight="0" />         <ToggleSwitch OnContent="ON" OffContent="OFF" Margin="3" Background="Blue" MinWidth="0" MinHeight="0" Padding="0"/>         <ToggleSwitch OnContent="ON" OffContent="OFF" Margin="3" Background="Red" MinWidth="0" MinHeight="0" Padding="0" Height="18" VerticalContentAlignment="Center"/>     </StackPanel> </Grid>

toggleswitch

Anyone have a work-around?

Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
747 questions
{count} votes

Accepted answer
  1. Tong Xu - MSFT 2,116 Reputation points Microsoft Vendor
    2023-12-22T09:39:59.5133333+00:00

    Dear @John Granatino
    Welcome to Microsoft Q&A!

    You can modify the default Style and ControlTemplate to give the control a unique appearance.

    1. First of all, find the file of generic.xaml from this location:
      generic
    2. Secondly, create <StackPanel.Resources> under <StackPanel>
      and copy the code into Resources.
      <Style x:Key="DefaultToggleSwitchStyle" TargetType="ToggleSwitch">
      ……
      ……
      </Style>
    3. Then, add a style object for TargetType"ToggleSwitch":
    <Style TargetType="ToggleSwitch" BasedOn="{StaticResource DefaultToggleSwitchStyle2}" /><Style x:Key="DefaultToggleSwitchStyle2" TargetType="ToggleSwitch">
    
    1. Last but not least, Modified the MinWidth and Height in ContentPresenter and Grid so that it can fit the internal padding or margins.h and w

    Height is 18 and this is before modifying:before

    After resetting the MinWidth, Height and fontsize:
    after

    This is my code:

    <Window
        
        x:Class="App1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
            
    
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
            <StackPanel.Resources>
                <Style TargetType="ToggleSwitch" BasedOn="{StaticResource DefaultToggleSwitchStyle2}" />
                <Style x:Key="DefaultToggleSwitchStyle2" TargetType="ToggleSwitch">
                    <Setter Property="Foreground" Value="{StaticResource ToggleSwitchForegroundThemeBrush}"/>
                    <Setter Property="HorizontalAlignment" Value="Left"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="HorizontalContentAlignment" Value="Left"/>
                    <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
                    <Setter Property="FontWeight" Value="SemiBold"/>
                    <Setter Property="FontSize" Value="7"/>
                    <Setter Property="ManipulationMode" Value="None"/>
                    <Setter Property="MinWidth" Value="154"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ToggleSwitch">
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal"/>
                                            <VisualState x:Name="PointerOver">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SwitchCurtain">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchCurtainPointerOverBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchTrackPointerOverBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SwitchKnob">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchThumbPointerOverBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="SwitchKnob">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchThumbPointerOverBorderThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Pressed">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SwitchCurtain">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchCurtainPressedBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchTrackPressedBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SwitchKnob">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchThumbPressedBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="SwitchKnob">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchThumbPressedForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Disabled">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="HeaderContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchHeaderDisabledForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="OffContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchDisabledForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="OnContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchDisabledForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="OuterBorder">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchOuterBorderDisabledBorderThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchTrackDisabledBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SwitchKnob">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchThumbDisabledBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="SwitchKnob">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchThumbDisabledBorderThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SwitchCurtain">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleSwitchCurtainDisabledBackgroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="ToggleStates">
                                            <VisualStateGroup.Transitions>
                                                <VisualTransition x:Name="DraggingToOnTransition" From="Dragging" GeneratedDuration="0" To="On">
                                                    <Storyboard>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.KnobCurrentToOnOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchKnob"/>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.CurtainCurrentToOnOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchCurtain"/>
                                                    </Storyboard>
                                                </VisualTransition>
                                                <VisualTransition x:Name="DraggingToOffTransition" From="Dragging" GeneratedDuration="0" To="Off">
                                                    <Storyboard>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.KnobCurrentToOffOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchKnob"/>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.CurtainCurrentToOffOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchCurtain"/>
                                                    </Storyboard>
                                                </VisualTransition>
                                                <VisualTransition x:Name="OnToOffTransition" From="On" GeneratedDuration="0" To="Off">
                                                    <Storyboard>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.KnobOnToOffOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchKnob"/>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.CurtainOnToOffOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchCurtain"/>
                                                    </Storyboard>
                                                </VisualTransition>
                                                <VisualTransition x:Name="OffToOnTransition" From="Off" GeneratedDuration="0" To="On">
                                                    <Storyboard>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.KnobOffToOnOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchKnob"/>
                                                        <RepositionThemeAnimation FromHorizontalOffset="{Binding TemplateSettings.CurtainOffToOnOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" TargetName="SwitchCurtain"/>
                                                    </Storyboard>
                                                </VisualTransition>
                                            </VisualStateGroup.Transitions>
                                            <VisualState x:Name="Dragging"/>
                                            <VisualState x:Name="Off">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="-44" Storyboard.TargetProperty="X" Storyboard.TargetName="CurtainTranslateTransform"/>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="On">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="CurtainTranslateTransform"/>
                                                    <DoubleAnimation Duration="0" To="38" Storyboard.TargetProperty="X" Storyboard.TargetName="KnobTranslateTransform"/>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="ContentStates">
                                            <VisualState x:Name="OffContent">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="OffContentPresenter"/>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="OffContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <x:Boolean>True</x:Boolean>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="OnContent">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="OnContentPresenter"/>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="OnContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <x:Boolean>True</x:Boolean>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="FocusStates">
                                            <VisualState x:Name="Focused">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhite"/>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlack"/>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Unfocused"/>
                                            <VisualState x:Name="PointerFocused"/>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{StaticResource ToggleSwitchHeaderForegroundThemeBrush}" FontWeight="Semilight" Margin="6"/>
                                        <Grid Margin="{TemplateBinding Padding}" Grid.Row="1">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="Auto"/>
                                                <ColumnDefinition Width="7"/>
                                                <ColumnDefinition Width="Auto"/>
                                            </Grid.ColumnDefinitions>
                                            <ContentPresenter x:Name="OffContentPresenter" ContentTemplate="{TemplateBinding OffContentTemplate}" Content="{TemplateBinding OffContent}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" Margin="5,5,5,5" 
                                                              MinWidth="20" Opacity="0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                            <ContentPresenter x:Name="OnContentPresenter" ContentTemplate="{TemplateBinding OnContentTemplate}" Content="{TemplateBinding OnContent}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" Margin="5,5,5,5" 
                                                              MinWidth="20" Opacity="0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                            <Grid Background="Transparent" Grid.Column="2">
                                                <Grid x:Name="SwitchKnobBounds" Height="20" Margin="0,0,0,0">
                                                    <Border x:Name="OuterBorder" BorderBrush="{StaticResource ToggleSwitchOuterBorderBorderThemeBrush}" BorderThickness="2">
                                                        <Border x:Name="InnerBorder" BorderBrush="{StaticResource ToggleSwitchTrackBorderThemeBrush}" BorderThickness="1" Background="{StaticResource ToggleSwitchTrackBackgroundThemeBrush}">
                                                            <ContentPresenter x:Name="SwitchCurtainBounds">
                                                                <ContentPresenter x:Name="SwitchCurtainClip">
                                                                    <Rectangle x:Name="SwitchCurtain" Fill="{StaticResource ToggleSwitchCurtainBackgroundThemeBrush}" Width="44">
                                                                        <Rectangle.RenderTransform>
                                                                            <TranslateTransform x:Name="CurtainTranslateTransform" X="-44"/>
                                                                        </Rectangle.RenderTransform>
                                                                    </Rectangle>
                                                                </ContentPresenter>
                                                            </ContentPresenter>
                                                        </Border>
                                                    </Border>
                                                    <Rectangle x:Name="SwitchKnob" Fill="{StaticResource ToggleSwitchThumbBackgroundThemeBrush}" HorizontalAlignment="Left" Stroke="{StaticResource ToggleSwitchThumbBorderThemeBrush}" StrokeThickness="1" Width="12">
                                                        <Rectangle.RenderTransform>
                                                            <TranslateTransform x:Name="KnobTranslateTransform"/>
                                                        </Rectangle.RenderTransform>
                                                    </Rectangle>
                                                    <Rectangle x:Name="FocusVisualWhite" Margin="-3" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
                                                    <Rectangle x:Name="FocusVisualBlack" Margin="-3" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
                                                </Grid>
                                                <Thumb x:Name="SwitchThumb">
                                                    <Thumb.Template>
                                                        <ControlTemplate TargetType="Thumb">
                                                            <Rectangle Fill="Transparent"/>
                                                        </ControlTemplate>
                                                    </Thumb.Template>
                                                </Thumb>
                                            </Grid>
                                        </Grid>
                                    </Grid>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </StackPanel.Resources>
    
    
                    <ToggleSwitch OnContent="ON" OffContent="OFF" Margin="3" Background="Red" MinWidth="0" MinHeight="0" Padding="0" Height="18" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
    
                
    
        </StackPanel>
        
    </Window>
    

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful