diff --git a/components/Primitives/samples/Primitives.Samples.csproj b/components/Primitives/samples/Primitives.Samples.csproj
index 3927b93a..63350207 100644
--- a/components/Primitives/samples/Primitives.Samples.csproj
+++ b/components/Primitives/samples/Primitives.Samples.csproj
@@ -63,22 +63,4 @@
PreserveNewest
-
-
-
- UniformGridSample.xaml
-
-
- DockPanelSample.xaml
-
-
- ConstrainedBoxSample.xaml
-
-
- StaggeredLayoutSample.xaml
-
-
- WrapPanelSample.xaml
-
-
diff --git a/components/Primitives/samples/SwitchPresenter.md b/components/Primitives/samples/SwitchPresenter.md
index 471de5a6..2c3590bc 100644
--- a/components/Primitives/samples/SwitchPresenter.md
+++ b/components/Primitives/samples/SwitchPresenter.md
@@ -29,3 +29,15 @@ Or it can simply be used to clearly display different outcomes based on some sta
`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:
> [!SAMPLE SwitchPresenterLoaderSample]
+
+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:
+
+> [!SAMPLE SwitchPresenterTemplateSample]
+
+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:
+
+> [!SAMPLE SwitchConverterBrushSample]
diff --git a/components/Primitives/samples/SwitchPresenter/SwitchConverterBrushSample.xaml b/components/Primitives/samples/SwitchPresenter/SwitchConverterBrushSample.xaml
new file mode 100644
index 00000000..400ebcb0
--- /dev/null
+++ b/components/Primitives/samples/SwitchPresenter/SwitchConverterBrushSample.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+ Warning
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Success
+ Warning
+ Error
+
+
+
+
+
diff --git a/components/Primitives/samples/SwitchPresenter/SwitchConverterBrushSample.xaml.cs b/components/Primitives/samples/SwitchPresenter/SwitchConverterBrushSample.xaml.cs
new file mode 100644
index 00000000..c8f259a0
--- /dev/null
+++ b/components/Primitives/samples/SwitchPresenter/SwitchConverterBrushSample.xaml.cs
@@ -0,0 +1,23 @@
+// 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,
+}
diff --git a/components/Primitives/samples/SwitchPresenter/SwitchPresenterLayoutSample.xaml.cs b/components/Primitives/samples/SwitchPresenter/SwitchPresenterLayoutSample.xaml.cs
index e5edd4e6..e6067234 100644
--- a/components/Primitives/samples/SwitchPresenter/SwitchPresenterLayoutSample.xaml.cs
+++ b/components/Primitives/samples/SwitchPresenter/SwitchPresenterLayoutSample.xaml.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using PrimitivesExperiment.Samples.ConstrainedBox;
-
namespace PrimitivesExperiment.Samples.SwitchPresenter;
[ToolkitSample(id: nameof(SwitchPresenterLayoutSample), "SwitchPresenter Layout", description: $"A sample for showing how to use a {nameof(SwitchPresenter)} for complex layouts.")]
diff --git a/components/Primitives/samples/SwitchPresenter/SwitchPresenterTemplateSample.xaml b/components/Primitives/samples/SwitchPresenter/SwitchPresenterTemplateSample.xaml
new file mode 100644
index 00000000..bd1df35c
--- /dev/null
+++ b/components/Primitives/samples/SwitchPresenter/SwitchPresenterTemplateSample.xaml
@@ -0,0 +1,54 @@
+
+
+
+
+ Confirmation Code
+ E-ticket number
+ Mileage Plan number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/Primitives/samples/SwitchPresenter/SwitchPresenterTemplateSample.xaml.cs b/components/Primitives/samples/SwitchPresenter/SwitchPresenterTemplateSample.xaml.cs
new file mode 100644
index 00000000..5858e90d
--- /dev/null
+++ b/components/Primitives/samples/SwitchPresenter/SwitchPresenterTemplateSample.xaml.cs
@@ -0,0 +1,24 @@
+// 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; }
+}
+
diff --git a/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml b/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml
index 807d3d57..9a8b2cf4 100644
--- a/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml
+++ b/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml
@@ -22,7 +22,11 @@
SelectedIndex="0" />
+ Value="{x:Bind AnimalPicker.SelectedItem, Mode=OneWay}">
+
+
+
@@ -31,14 +35,22 @@
-
+
+ Text="🦒" />
+
+
+
+
+
+
diff --git a/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml.cs b/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml.cs
index 0fb2f77e..f08a62de 100644
--- a/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml.cs
+++ b/components/Primitives/samples/SwitchPresenter/SwitchPresenterValueSample.xaml.cs
@@ -15,10 +15,13 @@ public SwitchPresenterValueSample()
public enum Animal
{
+ Bunny,
Cat,
Dog,
- Bunny,
+ Giraffe,
Llama,
+ Otter,
+ Owl,
Parrot,
Squirrel
}
diff --git a/components/Primitives/src/SwitchPresenter/Case.cs b/components/Primitives/src/SwitchPresenter/Case.cs
index d3551f1f..0e95634a 100644
--- a/components/Primitives/src/SwitchPresenter/Case.cs
+++ b/components/Primitives/src/SwitchPresenter/Case.cs
@@ -13,9 +13,9 @@ public partial class Case : DependencyObject
///
/// Gets or sets the Content to display when this case is active.
///
- public UIElement Content
+ public object Content
{
- get { return (UIElement)GetValue(ContentProperty); }
+ get { return (object)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
@@ -23,7 +23,7 @@ public UIElement Content
/// Identifies the property.
///
public static readonly DependencyProperty ContentProperty =
- DependencyProperty.Register(nameof(Content), typeof(UIElement), typeof(Case), new PropertyMetadata(null));
+ DependencyProperty.Register(nameof(Content), typeof(object), typeof(Case), new PropertyMetadata(null));
///
/// Gets or sets a value indicating whether this is the default case to display when no values match the specified value in the . There should only be a single default case provided. Do not set the property when setting to true. Default is false.
diff --git a/components/Primitives/src/SwitchPresenter/SwitchConverter.cs b/components/Primitives/src/SwitchPresenter/SwitchConverter.cs
new file mode 100644
index 00000000..7ce8bad2
--- /dev/null
+++ b/components/Primitives/src/SwitchPresenter/SwitchConverter.cs
@@ -0,0 +1,80 @@
+// 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.Controls;
+
+namespace CommunityToolkit.WinUI.Converters;
+
+///
+/// A helper which can automatically translate incoming data to a set of resulting values defined in XAML.
+///
+///
+/// <converters:SwitchConverter x:Key="StatusToColorSwitchConverter"
+/// TargetType="models:CheckStatus">
+/// <controls:Case Value="Error" Content="{ThemeResource SystemFillColorCriticalBrush}"/>
+/// <controls:Case Value="Warning" Content="{ThemeResource SystemFillColorCautionBrush}"/>
+/// <controls:Case Value="Success" Content="{ThemeResource SystemFillColorSuccessBrush}"/>
+/// </converters:SwitchConverter>
+/// ...
+/// <TextBlock
+/// FontWeight="SemiBold"
+/// Foreground="{x:Bind Status, Converter={StaticResource StatusToColorSwitchConverter}}"
+/// Text = "{x:Bind Status}" />
+///
+[ContentProperty(Name = nameof(SwitchCases))]
+public sealed partial class SwitchConverter : DependencyObject, IValueConverter
+{
+ ///
+ /// Gets or sets a value representing the collection of cases to evaluate.
+ ///
+ public CaseCollection SwitchCases
+ {
+ get { return (CaseCollection)GetValue(SwitchCasesProperty); }
+ set { SetValue(SwitchCasesProperty, value); }
+ }
+
+ ///
+ /// Identifies the property.
+ ///
+ public static readonly DependencyProperty SwitchCasesProperty =
+ DependencyProperty.Register(nameof(SwitchCases), typeof(CaseCollection), typeof(SwitchConverter), new PropertyMetadata(null));
+
+ ///
+ /// Gets or sets a value indicating which type to first cast and compare provided values against.
+ ///
+ public Type TargetType
+ {
+ get { return (Type)GetValue(TargetTypeProperty); }
+ set { SetValue(TargetTypeProperty, value); }
+ }
+
+ ///
+ /// Identifies the property.
+ ///
+ public static readonly DependencyProperty TargetTypeProperty =
+ DependencyProperty.Register(nameof(TargetType), typeof(Type), typeof(SwitchConverter), new PropertyMetadata(null));
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SwitchConverter()
+ {
+ // Note: we need to initialize this here so that XAML can automatically add cases without needing this defined around it as the content.
+ // We don't do this in the PropertyMetadata as then we create a static shared collection for all converters, which we don't want. We want it per instance.
+ // See https://learn.microsoft.com/windows/uwp/xaml-platform/custom-dependency-properties#initializing-the-collection
+ SwitchCases = new CaseCollection();
+ }
+
+ public object Convert(object value, Type targetType, object parameter, string language)
+ {
+ var result = SwitchCases.EvaluateCases(value, TargetType ?? targetType);
+
+ return result?.Content!;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, string language)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/components/Primitives/src/SwitchPresenter/SwitchHelpers.cs b/components/Primitives/src/SwitchPresenter/SwitchHelpers.cs
new file mode 100644
index 00000000..c3698931
--- /dev/null
+++ b/components/Primitives/src/SwitchPresenter/SwitchHelpers.cs
@@ -0,0 +1,135 @@
+// 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 CommunityToolkit.WinUI.Controls;
+
+///
+/// Internal helpers for use between and .
+/// The logic here is the main code which looks across a to match a specific with a given value while converting types based on the property. This will handle values as well as values compatible with the method.
+///
+internal static partial class SwitchHelpers
+{
+ ///
+ /// Extension method for a set of cases to find the matching case given its value and type.
+ ///
+ /// The collection of s in a
+ /// The value of the to find
+ /// The desired type of the result for automatic conversion
+ /// The discovered value, the default value, or null
+ internal static Case? EvaluateCases(this CaseCollection switchCases, object value, Type targetType)
+ {
+ if (switchCases == null ||
+ switchCases.Count == 0)
+ {
+ // If we have no cases, then we can't match anything.
+ return null;
+ }
+
+ Case? xdefault = null;
+ Case? newcase = null;
+
+ foreach (Case xcase in switchCases)
+ {
+ if (xcase.IsDefault)
+ {
+ // If there are multiple default cases provided, this will override and just grab the last one, the developer will have to fix this in their XAML. We call this out in the case comments.
+ xdefault = xcase;
+ continue;
+ }
+
+ if (CompareValues(value, xcase.Value, targetType))
+ {
+ newcase = xcase;
+ break;
+ }
+ }
+
+ if (newcase == null && xdefault != null)
+ {
+ // Inject default if we found one without matching anything
+ newcase = xdefault;
+ }
+
+ return newcase;
+ }
+
+ ///
+ /// Compares two values using the TargetType.
+ ///
+ /// Our main value in our SwitchPresenter.
+ /// The value from the case to compare to.
+ /// true if the two values are equal
+ internal static bool CompareValues(object compare, object value, Type targetType)
+ {
+ if (compare == null || value == null)
+ {
+ return compare == value;
+ }
+
+ if (targetType == null ||
+ (targetType == compare.GetType() &&
+ targetType == value.GetType()))
+ {
+ // Default direct object comparison or we're all the proper type
+ return compare.Equals(value);
+ }
+ else if (compare.GetType() == targetType)
+ {
+ // If we have a TargetType and the first value is the right type
+ // Then our 2nd value isn't, so convert to string and coerce.
+ var valueBase2 = ConvertValue(targetType, value);
+
+ return compare.Equals(valueBase2);
+ }
+
+ // Neither of our two values matches the type so
+ // we'll convert both to a String and try and coerce it to the proper type.
+ var compareBase = ConvertValue(targetType, compare);
+
+ var valueBase = ConvertValue(targetType, value);
+
+ return compareBase.Equals(valueBase);
+ }
+
+ ///
+ /// Helper method to convert a value from a source type to a target type.
+ ///
+ /// The target type
+ /// The value to convert
+ /// The converted value
+ internal static object ConvertValue(Type targetType, object value)
+ {
+ if (targetType.IsInstanceOfType(value))
+ {
+ return value;
+ }
+ else if (targetType.IsEnum && value is string str)
+ {
+#if HAS_UNO
+ if (Enum.IsDefined(targetType, str))
+ {
+ return Enum.Parse(targetType, str);
+ }
+#else
+ if (Enum.TryParse(targetType, str, out object? result))
+ {
+ return result!;
+ }
+#endif
+
+ static object ThrowExceptionForKeyNotFound()
+ {
+ throw new InvalidOperationException("The requested enum value was not present in the provided type.");
+ }
+
+ return ThrowExceptionForKeyNotFound();
+ }
+ else
+ {
+ return XamlBindingHelper.ConvertValue(targetType, value);
+ }
+ }
+}
diff --git a/components/Primitives/src/SwitchPresenter/SwitchPresenter.cs b/components/Primitives/src/SwitchPresenter/SwitchPresenter.cs
index 870da7dc..9ebc6b6e 100644
--- a/components/Primitives/src/SwitchPresenter/SwitchPresenter.cs
+++ b/components/Primitives/src/SwitchPresenter/SwitchPresenter.cs
@@ -115,20 +115,7 @@ protected override void OnApplyTemplate()
private void EvaluateCases()
{
- if (SwitchCases == null ||
- SwitchCases.Count == 0)
- {
- // If we have no cases, then we can't match anything.
- if (CurrentCase != null)
- {
- // Only bother clearing our actual content if we had something before.
- Content = null;
- CurrentCase = null;
- }
-
- return;
- }
- else if (CurrentCase?.Value != null &&
+ if (CurrentCase?.Value != null &&
CurrentCase.Value.Equals(Value))
{
// If the current case we're on already matches our current value,
@@ -136,114 +123,14 @@ private void EvaluateCases()
return;
}
- Case? xdefault = null;
- Case? newcase = null;
-
- foreach (Case xcase in SwitchCases)
- {
- if (xcase.IsDefault)
- {
- // If there are multiple default cases provided, this will override and just grab the last one, the developer will have to fix this in their XAML. We call this out in the case comments.
- xdefault = xcase;
- continue;
- }
-
- if (CompareValues(Value, xcase.Value))
- {
- newcase = xcase;
- break;
- }
- }
-
- if (newcase == null && xdefault != null)
- {
- // Inject default if we found one without matching anything
- newcase = xdefault;
- }
+ var result = SwitchCases.EvaluateCases(Value, TargetType);
- // Only bother changing things around if we actually have a new case.
- if (newcase != CurrentCase)
+ // Only bother changing things around if we actually have a new case. (this should handle prior null case as well)
+ if (result != CurrentCase)
{
// If we don't have any cases or default, setting these to null is what we want to be blank again.
- Content = newcase?.Content;
- CurrentCase = newcase;
- }
- }
-
- ///
- /// Compares two values using the TargetType.
- ///
- /// Our main value in our SwitchPresenter.
- /// The value from the case to compare to.
- /// true if the two values are equal
- private bool CompareValues(object compare, object value)
- {
- if (compare == null || value == null)
- {
- return compare == value;
- }
-
- if (TargetType == null ||
- (TargetType == compare.GetType() &&
- TargetType == value.GetType()))
- {
- // Default direct object comparison or we're all the proper type
- return compare.Equals(value);
- }
- else if (compare.GetType() == TargetType)
- {
- // If we have a TargetType and the first value is the right type
- // Then our 2nd value isn't, so convert to string and coerce.
- var valueBase2 = ConvertValue(TargetType, value);
-
- return compare.Equals(valueBase2);
- }
-
- // Neither of our two values matches the type so
- // we'll convert both to a String and try and coerce it to the proper type.
- var compareBase = ConvertValue(TargetType, compare);
-
- var valueBase = ConvertValue(TargetType, value);
-
- return compareBase.Equals(valueBase);
- }
-
- ///
- /// Helper method to convert a value from a source type to a target type.
- ///
- /// The target type
- /// The value to convert
- /// The converted value
- internal static object ConvertValue(Type targetType, object value)
- {
- if (targetType.IsInstanceOfType(value))
- {
- return value;
- }
- else if (targetType.IsEnum && value is string str)
- {
-#if HAS_UNO
- if (Enum.IsDefined(targetType, str))
- {
- return Enum.Parse(targetType, str);
- }
-#else
- if (Enum.TryParse(targetType, str, out object? result))
- {
- return result!;
- }
-#endif
-
- static object ThrowExceptionForKeyNotFound()
- {
- throw new InvalidOperationException("The requested enum value was not present in the provided type.");
- }
-
- return ThrowExceptionForKeyNotFound();
- }
- else
- {
- return XamlBindingHelper.ConvertValue(targetType, value);
+ Content = result?.Content;
+ CurrentCase = result;
}
}
}
diff --git a/components/Primitives/tests/Primitives.Tests.projitems b/components/Primitives/tests/Primitives.Tests.projitems
index 344de9e5..efdf851b 100644
--- a/components/Primitives/tests/Primitives.Tests.projitems
+++ b/components/Primitives/tests/Primitives.Tests.projitems
@@ -9,6 +9,13 @@
PrimitivesExperiment.Tests
+
+ %(Filename)
+
+
+ %(Filename)
+
+
@@ -33,4 +40,14 @@
MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
\ No newline at end of file
diff --git a/components/Primitives/tests/SwitchPresenter/SwitchConverterBrushSample.xaml b/components/Primitives/tests/SwitchPresenter/SwitchConverterBrushSample.xaml
new file mode 100644
index 00000000..9d6820e3
--- /dev/null
+++ b/components/Primitives/tests/SwitchPresenter/SwitchConverterBrushSample.xaml
@@ -0,0 +1,53 @@
+
+
+
+
+ Warning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Success
+ Warning
+ Error
+
+
+
+
diff --git a/components/Primitives/tests/SwitchPresenter/SwitchConverterBrushSample.xaml.cs b/components/Primitives/tests/SwitchPresenter/SwitchConverterBrushSample.xaml.cs
new file mode 100644
index 00000000..d5319277
--- /dev/null
+++ b/components/Primitives/tests/SwitchPresenter/SwitchConverterBrushSample.xaml.cs
@@ -0,0 +1,20 @@
+// 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.Tests;
+
+public sealed partial class SwitchConverterBrushSample : Page
+{
+ public SwitchConverterBrushSample()
+ {
+ this.InitializeComponent();
+ }
+}
+
+public enum CheckStatus
+{
+ Error,
+ Warning,
+ Success,
+}
diff --git a/components/Primitives/tests/SwitchPresenter/SwitchPresenterLayoutSample.xaml b/components/Primitives/tests/SwitchPresenter/SwitchPresenterLayoutSample.xaml
new file mode 100644
index 00000000..6465b41b
--- /dev/null
+++ b/components/Primitives/tests/SwitchPresenter/SwitchPresenterLayoutSample.xaml
@@ -0,0 +1,54 @@
+
+
+
+
+ Select an option
+ Confirmation Code
+ E-ticket number
+ Mileage Plan number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/Primitives/tests/SwitchPresenter/SwitchPresenterLayoutSample.xaml.cs b/components/Primitives/tests/SwitchPresenter/SwitchPresenterLayoutSample.xaml.cs
new file mode 100644
index 00000000..d6cbcb1b
--- /dev/null
+++ b/components/Primitives/tests/SwitchPresenter/SwitchPresenterLayoutSample.xaml.cs
@@ -0,0 +1,13 @@
+// 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.Tests;
+
+public sealed partial class SwitchPresenterLayoutSample : Page
+{
+ public SwitchPresenterLayoutSample()
+ {
+ this.InitializeComponent();
+ }
+}
diff --git a/components/Primitives/tests/SwitchPresenter/SwitchPresenterTests.cs b/components/Primitives/tests/SwitchPresenter/SwitchPresenterTests.cs
new file mode 100644
index 00000000..63b5862a
--- /dev/null
+++ b/components/Primitives/tests/SwitchPresenter/SwitchPresenterTests.cs
@@ -0,0 +1,142 @@
+// 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.Tests;
+using CommunityToolkit.Tooling.TestGen;
+using CommunityToolkit.WinUI.Controls;
+using CommunityToolkit.WinUI.Converters;
+
+namespace PrimitivesExperiment.Tests;
+
+[TestClass]
+public partial class SwitchPresenterTests : VisualUITestBase
+{
+ [UIThreadTestMethod]
+ public async Task SwitchPresenterLayoutTest(SwitchPresenterLayoutSample page)
+ {
+ var spresenter = page.FindDescendant();
+ var combobox = page.FindDescendant();
+
+ Assert.IsNotNull(spresenter, "Couldn't find SwitchPresenter");
+ Assert.IsNotNull(combobox, "Couldn't find ComboBox");
+
+ var dcase = spresenter.SwitchCases.OfType().FirstOrDefault(@case => @case.IsDefault);
+
+ Assert.IsNotNull(dcase, "Couldn't find default case");
+
+ // Are we in our initial case?
+ Assert.AreEqual("Select an option", spresenter.Value, "SwitchPresenter not expected starting value");
+ Assert.AreEqual(dcase, spresenter.CurrentCase, "SwitchPresenter not at current default case");
+
+ // Can we find our matching textbox?
+ var tbox = spresenter.FindDescendant();
+ Assert.IsNotNull(tbox, "Couldn't find inner textbox");
+ Assert.AreEqual("Please select a way to lookup your reservation above...", tbox.Text, "Unexpected content for SwitchPresenter default case");
+
+ // Update combobox
+ combobox.SelectedIndex = 1;
+
+ // Wait for update
+ await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { });
+
+ // Are we in the new case?
+ Assert.AreEqual("Confirmation Code", spresenter.Value);
+
+ var ccase = spresenter.SwitchCases.OfType().FirstOrDefault(@case => @case.Value?.ToString() == "Confirmation Code");
+
+ Assert.IsNotNull(ccase, "Couldn't find expected case");
+
+ Assert.AreEqual(ccase, spresenter.CurrentCase, "SwitchPresenter didn't change cases");
+
+ var txtbox = spresenter.FindDescendant();
+ Assert.IsNotNull(txtbox, "Couldn't find new textbox");
+ Assert.AreEqual("Confirmation code", txtbox.Header, "Textbox header not expected value");
+ }
+
+ [UIThreadTestMethod]
+ public async Task SwitchConverterBrushTest(SwitchConverterBrushSample page)
+ {
+ var combobox = page.FindDescendant();
+ var textblock = page.FindDescendant("ResultBlock") as TextBlock;
+
+ Assert.IsNotNull(combobox, "Couldn't find ComboBox");
+ Assert.IsNotNull(textblock, "Couldn't find SwitchPresenter");
+
+ // Are we in our initial case?
+ Assert.AreEqual(0, combobox.SelectedIndex, "ComboBox not initialized");
+ Assert.AreEqual("Success", combobox.SelectedItem, "Not expected starting value in ComboBox");
+
+ // Check the TextBlock's brush
+ Assert.AreEqual(((SolidColorBrush)page.Resources["SystemFillColorSuccessBrush"]).Color, ((SolidColorBrush)textblock.Foreground).Color, "TextBlock not in initial success state");
+
+ // Update combobox
+ combobox.SelectedIndex = 1;
+
+ // Wait for update
+ await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { });
+
+ // Are we in the new case?
+ Assert.AreEqual("Warning", combobox.SelectedItem, "ComboBox didn't change");
+
+ // Check the TextBlock's brush
+ Assert.AreEqual(((SolidColorBrush)page.Resources["SystemFillColorCautionBrush"]).Color, ((SolidColorBrush)textblock.Foreground).Color, "TextBlock not in new state");
+
+ // Update combobox
+ combobox.SelectedIndex = 2;
+
+ // Wait for update
+ await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { });
+
+ // Are we in the new case?
+ Assert.AreEqual("Error", combobox.SelectedItem, "ComboBox didn't change 2");
+
+ // Check the TextBlock's brush
+ Assert.AreEqual(((SolidColorBrush)page.Resources["SystemFillColorCriticalBrush"]).Color, ((SolidColorBrush)textblock.Foreground).Color, "TextBlock not in final state");
+ }
+
+ [UIThreadTestMethod]
+ public void SwitchConverterDirectTest()
+ {
+ // Multiply by 10
+ SwitchConverter sconverter = new()
+ {
+ SwitchCases = new CaseCollection {
+ new Case()
+ {
+ Content = 10,
+ Value = 1,
+ },
+ new Case()
+ {
+ Content = 50,
+ Value = 5,
+ IsDefault = true
+ },
+ new Case()
+ {
+ Content = 30,
+ Value = 3,
+ },
+ new Case()
+ {
+ Content = 20,
+ Value = 2,
+ },
+ },
+ TargetType = typeof(int)
+ };
+
+ Assert.IsNotNull(sconverter);
+ Assert.AreEqual(4, sconverter.SwitchCases.Count, "Not 4 cases");
+
+ var @default = sconverter.Convert(100, typeof(int), string.Empty, string.Empty);
+
+ Assert.AreEqual(50, @default, "Unexpected default return");
+
+ Assert.AreEqual(10, sconverter.Convert(1, typeof(int), string.Empty, string.Empty), "Unexpected result with 1");
+ Assert.AreEqual(20, sconverter.Convert(2, typeof(int), string.Empty, string.Empty), "Unexpected result with 2");
+ Assert.AreEqual(30, sconverter.Convert(3, typeof(int), string.Empty, string.Empty), "Unexpected result with 3");
+ Assert.AreEqual(50, sconverter.Convert(5, typeof(int), string.Empty, string.Empty), "Unexpected result with 5");
+ }
+}