Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The SwitchPresenter control acts like a switch statement for XAML. It allows a developer to display certain content based on the condition of another value as an alternative to managing multiple Visibility values or complex visual states.
Unlike traditional approaches of showing/hiding components within a page, the SwitchPresenter will only load and attach the matching Case's content to the Visual Tree.
Examples
SwitchPresenter can make it easier to follow complex layout changes or layouts with varying logic that are based on a property, for instance the type of ticketing mode for an airline:
<Page x:Class="PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterLayoutSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<StackPanel>
<ComboBox x:Name="Lookup"
Margin="0,0,0,8"
Header="Look up reservation"
SelectedIndex="0">
<x:String>Select an option</x:String>
<x:String>Confirmation Code</x:String>
<x:String>E-ticket number</x:String>
<x:String>Mileage Plan number</x:String>
</ComboBox>
<!-- SwitchPresenter binds to a value -->
<controls:SwitchPresenter Value="{Binding SelectedItem, ElementName=Lookup}">
<!-- And then only dynamically displays the Case with the matching Value -->
<controls:Case Value="Confirmation Code">
<StackPanel>
<TextBox Name="ConfirmationCodeValidator"
ui:TextBoxExtensions.Regex="^[a-zA-Z]{6}$"
Header="Confirmation code"
PlaceholderText="6 letters" />
<TextBlock Text="Thanks for entering a valid code!"
Visibility="{Binding (ui:TextBoxExtensions.IsValid), ElementName=ConfirmationCodeValidator}" />
</StackPanel>
</controls:Case>
<controls:Case Value="E-ticket number">
<StackPanel>
<TextBox Name="TicketValidator"
ui:TextBoxExtensions.Regex="(^\d{10}$)|(^\d{13}$)"
Header="E-ticket number"
PlaceholderText="10 or 13 numbers" />
<TextBlock Text="Thanks for entering a valid code!"
Visibility="{Binding (ui:TextBoxExtensions.IsValid), ElementName=TicketValidator}" />
</StackPanel>
</controls:Case>
<controls:Case Value="Mileage Plan number">
<TextBox Name="PlanValidator"
Header="Mileage Plan #"
PlaceholderText="Mileage Plan #" />
</controls:Case>
<!-- You can also provide a default case if no match is found -->
<controls:Case IsDefault="True">
<TextBlock Text="Please select a way to lookup your reservation above..." />
</controls:Case>
</controls:SwitchPresenter>
</StackPanel>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace PrimitivesExperiment.Samples.SwitchPresenter;
[ToolkitSample(id: nameof(SwitchPresenterLayoutSample), "SwitchPresenter Layout", description: $"A sample for showing how to use a {nameof(SwitchPresenter)} for complex layouts.")]
public sealed partial class SwitchPresenterLayoutSample : Page
{
public SwitchPresenterLayoutSample()
{
this.InitializeComponent();
}
}
Or it can simply be used to clearly display different outcomes based on some state which can be useful for a NavigationView or with a simple enum as in the following example:
<Page x:Class="PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:PrimitivesExperiment.Samples.SwitchPresenter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Page.Resources>
<!--
If you reference an enum directly in UWP, you need to use it somewhere for the XamlTypeInfo reference to be generated...
-->
<local:Animal x:Key="MyAnimal">Cat</local:Animal>
</Page.Resources>
<StackPanel>
<ComboBox x:Name="AnimalPicker"
Header="Pick an Animal"
ItemsSource="{ui:EnumValues Type=local:Animal}"
SelectedIndex="0" />
<controls:SwitchPresenter Padding="16"
TargetType="local:Animal"
Value="{x:Bind AnimalPicker.SelectedItem, Mode=OneWay}">
<controls:Case Value="Bunny">
<TextBlock FontSize="32"
Text="🐇" />
</controls:Case>
<controls:Case Value="Cat">
<TextBlock FontSize="32"
Text="🐈" />
</controls:Case>
<controls:Case Value="Dog">
<TextBlock FontSize="32"
Text="🐕" />
</controls:Case>
<controls:Case Value="Giraffe">
<TextBlock FontSize="32"
Text="🦒" />
</controls:Case>
<controls:Case Value="Llama">
<TextBlock FontSize="32"
Text="🦙" />
</controls:Case>
<controls:Case Value="Otter">
<TextBlock FontSize="32"
Text="🦦" />
</controls:Case>
<controls:Case Value="Owl">
<TextBlock FontSize="32"
Text="🦉" />
</controls:Case>
<controls:Case Value="Parrot">
<TextBlock FontSize="32"
Text="🦜" />
</controls:Case>
<controls:Case Value="Squirrel">
<TextBlock FontSize="32"
Text="🐿" />
</controls:Case>
</controls:SwitchPresenter>
</StackPanel>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace PrimitivesExperiment.Samples.SwitchPresenter;
[ToolkitSample(id: nameof(SwitchPresenterValueSample), "SwitchPresenter Value", description: $"A sample for showing how to use a {nameof(SwitchPresenter)} for state changes from an enum.")]
public sealed partial class SwitchPresenterValueSample : Page
{
public SwitchPresenterValueSample()
{
this.InitializeComponent();
}
}
public enum Animal
{
Bunny,
Cat,
Dog,
Giraffe,
Llama,
Otter,
Owl,
Parrot,
Squirrel
}
SwitchPresenter can also be used as a replacement for the deprecated Loading control. This provides more fine-grained control over animations and content within each state:
<Page x:Class="PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterLoaderSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:PrimitivesExperiment.Samples.SwitchPresenter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Page.Resources>
<animations:ImplicitAnimationSet x:Name="ShowTransitions">
<animations:OffsetAnimation EasingMode="EaseOut"
From="0,24,0"
To="0"
Duration="0:0:0.4" />
<animations:OpacityAnimation EasingMode="EaseOut"
From="0"
To="1"
Duration="0:0:0.2" />
</animations:ImplicitAnimationSet>
<animations:ImplicitAnimationSet x:Name="HideTransitions">
<animations:OffsetAnimation EasingMode="EaseOut"
From="0"
To="0,24,0"
Duration="0:0:0.2" />
<animations:OpacityAnimation EasingMode="EaseOut"
From="1"
To="0"
Duration="0:0:0.1" />
</animations:ImplicitAnimationSet>
</Page.Resources>
<Grid Padding="16">
<controls:SwitchPresenter HorizontalAlignment="Center"
TargetType="x:Boolean"
Value="{x:Bind LoadingState, Mode=OneWay}">
<controls:Case Value="True">
<StackPanel HorizontalAlignment="Center"
animations:Implicit.HideAnimations="{StaticResource HideTransitions}"
animations:Implicit.ShowAnimations="{StaticResource ShowTransitions}"
Orientation="Vertical"
Spacing="8">
<muxc:ProgressRing IsActive="{x:Bind LoadingState, Mode=OneWay}" />
<TextBlock HorizontalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="Fetching data.." />
</StackPanel>
</controls:Case>
<controls:Case Value="False">
<TextBlock HorizontalAlignment="Center"
animations:Implicit.HideAnimations="{StaticResource HideTransitions}"
animations:Implicit.ShowAnimations="{StaticResource ShowTransitions}"
TextAlignment="Center"
TextWrapping="WrapWholeWords">
<Run FontWeight="SemiBold"
Text="Content has loaded" />
<LineBreak />
<Run Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." />
</TextBlock>
</controls:Case>
</controls:SwitchPresenter>
</Grid>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace PrimitivesExperiment.Samples.SwitchPresenter;
[ToolkitSampleBoolOption("LoadingState", true, Title = "IsLoading")]
[ToolkitSample(id: nameof(SwitchPresenterLoaderSample), "SwitchPresenter Loader", description: $"A sample for showing how to use a {nameof(SwitchPresenter)} to show a loading UI when data is loading.")]
public sealed partial class SwitchPresenterLoaderSample : Page
{
public SwitchPresenterLoaderSample()
{
this.InitializeComponent();
}
}
We can also invert the paradigm a bit with a SwitchPresenter to do data transformations within XAML using a ContentTemplate. Imagine an alternate view of our first starting example:
<Page x:Class="PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterTemplateSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:PrimitivesExperiment.Samples.SwitchPresenter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<StackPanel>
<ComboBox x:Name="Lookup"
Margin="0,0,0,8"
Header="Look up reservation"
SelectedIndex="0">
<x:String>Confirmation Code</x:String>
<x:String>E-ticket number</x:String>
<x:String>Mileage Plan number</x:String>
</ComboBox>
<!-- SwitchPresenter binds to a value -->
<controls:SwitchPresenter Value="{x:Bind Lookup.SelectedItem, Mode=OneWay}">
<!-- We define a common UI template for the data we want to display -->
<controls:SwitchPresenter.ContentTemplate>
<DataTemplate x:DataType="local:TemplateInformation">
<StackPanel>
<TextBox Name="CodeValidator"
ui:TextBoxExtensions.Regex="{x:Bind Regex, Mode=OneWay}"
Header="{x:Bind Header, Mode=OneWay}"
PlaceholderText="{x:Bind PlaceholderText, Mode=OneWay}" />
<TextBlock Text="Thanks for entering a valid code!"
Visibility="{Binding (ui:TextBoxExtensions.IsValid), ElementName=CodeValidator}" />
</StackPanel>
</DataTemplate>
</controls:SwitchPresenter.ContentTemplate>
<!-- And use the value to transform our data into an object we'll use as the context for our UI -->
<controls:Case IsDefault="True"
Value="Confirmation Code">
<local:TemplateInformation Header="Confirmation code"
PlaceholderText="6 letters"
Regex="^[a-zA-Z]{6}$" />
</controls:Case>
<controls:Case Value="E-ticket number">
<local:TemplateInformation Header="E-ticket number"
PlaceholderText="10 or 13 numbers"
Regex="(^\d{10}$)|(^\d{13}$)" />
</controls:Case>
<controls:Case Value="Mileage Plan number">
<local:TemplateInformation Header="Mileage Plan #"
PlaceholderText="Mileage Plan (12 digits)"
Regex="(^\d{12}$)" />
</controls:Case>
</controls:SwitchPresenter>
</StackPanel>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace PrimitivesExperiment.Samples.SwitchPresenter;
[ToolkitSample(id: nameof(SwitchPresenterTemplateSample), "SwitchPresenter Template", description: $"A sample for showing how to use a {nameof(SwitchPresenter)} with a Content Template.")]
public sealed partial class SwitchPresenterTemplateSample : Page
{
public SwitchPresenterTemplateSample()
{
this.InitializeComponent();
}
}
public partial class TemplateInformation
{
public string? Header { get; set; }
public string? Regex { get; set; }
public string? PlaceholderText { get; set; }
}
That's right! SwitchPresenter can be used not just for displaying different UIElements but in feeding different kinds of data into the ContentTemplate as well.
SwitchConverter
A new analog to SwitchPresenter is the SwitchConverter which can be used in bindings to translate values into resources:
<Page x:Class="PrimitivesExperiment.Samples.SwitchPresenter.SwitchConverterBrushSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:PrimitivesExperiment.Samples.SwitchPresenter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Page.Resources>
<!--
If you reference an enum directly in UWP, you need to use it somewhere for the XamlTypeInfo reference to be generated...
-->
<local:CheckStatus x:Key="MyChecks">Warning</local:CheckStatus>
<!-- SwitchConverter lets you easily convert general values to resources -->
<!-- Note: This is in the converters namespace -->
<converters:SwitchConverter x:Key="StatusToColorSwitchConverter"
TargetType="local:CheckStatus">
<!-- Note: These are reused from the controls namespace from SwitchPresenter -->
<controls:Case Content="{ThemeResource SystemFillColorSuccessBrush}"
Value="Success" />
<controls:Case Content="{ThemeResource SystemFillColorCautionBrush}"
Value="Warning" />
<controls:Case Content="{ThemeResource SystemFillColorCriticalBrush}"
Value="Error" />
</converters:SwitchConverter>
</Page.Resources>
<StackPanel Spacing="8">
<ComboBox x:Name="StatusPicker"
Header="Pick a status"
SelectedIndex="0">
<x:String>Success</x:String>
<x:String>Warning</x:String>
<x:String>Error</x:String>
</ComboBox>
<TextBlock Text="This is it, this is the demo:" />
<TextBlock FontWeight="SemiBold"
Foreground="{x:Bind StatusPicker.SelectedItem, Converter={StaticResource StatusToColorSwitchConverter}, Mode=OneWay}"
Text="{x:Bind StatusPicker.SelectedItem, Mode=OneWay}" />
</StackPanel>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.WinUI.Converters;
namespace PrimitivesExperiment.Samples.SwitchPresenter;
[ToolkitSample(id: nameof(SwitchConverterBrushSample), "SwitchConverter Brush", description: $"A sample for showing how to use a {nameof(SwitchConverter)} for swapping a brush based on an enum.")]
public sealed partial class SwitchConverterBrushSample : Page
{
public SwitchConverterBrushSample()
{
this.InitializeComponent();
}
}
public enum CheckStatus
{
Error,
Warning,
Success,
}
Windows Community Toolkit