diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj
index adbb2251c0b..d04d0deac93 100644
--- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj
+++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj
@@ -520,6 +520,9 @@
ImageExLazyLoadingControl.xaml
+
+ IconExtensionsPage.xaml
+ ObservableGroupPage.xaml
@@ -581,6 +584,7 @@
+
@@ -990,6 +994,10 @@
DesignerMSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+ DesignerMSBuild:Compile
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml
new file mode 100644
index 00000000000..2655dda17d8
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml.cs
new file mode 100644
index 00000000000..0311ad04acf
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml.cs
@@ -0,0 +1,30 @@
+// 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 System.Linq;
+using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors;
+using Microsoft.Toolkit.Uwp.UI.Extensions;
+using Microsoft.Xaml.Interactivity;
+using Windows.UI.Xaml;
+
+namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
+{
+ ///
+ /// A page that shows how to use the offset behavior.
+ ///
+ public sealed partial class IconExtensionsPage : IXamlRenderListener
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public IconExtensionsPage()
+ {
+ InitializeComponent();
+ }
+
+ public void OnXamlRendered(FrameworkElement control)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsXaml.bind
new file mode 100644
index 00000000000..48507ef0c43
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsXaml.bind
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json
index b17ca65a36c..ae9142c545f 100644
--- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json
@@ -1223,7 +1223,16 @@
"Icon": "/SamplePages/OnDevice/OnDevice.png",
"XamlCodeFile": "OnDeviceXaml.bind",
"DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/OnDeviceMarkup.md"
- }
+ },
+ {
+ "Name": "IconExtensions",
+ "Type": "IconExtensionsPage",
+ "About": "Markup extensions to easily create various types of icons.",
+ "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconExtension",
+ "XamlCodeFile": "IconExtensionsXaml.bind",
+ "Icon": "/Assets/Helpers.png",
+ "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/IconExtensions.md"
+ }
]
},
{
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/Abstract/TextIconExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/Abstract/TextIconExtension.cs
new file mode 100644
index 00000000000..4640b476687
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/Abstract/TextIconExtension.cs
@@ -0,0 +1,58 @@
+// 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 System;
+using Windows.UI.Text;
+using Windows.UI.Xaml.Markup;
+using Windows.UI.Xaml.Media;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// An abstract which to produce text-based icons.
+ ///
+ public abstract class TextIconExtension : MarkupExtension
+ {
+ ///
+ /// Gets or sets the size of the icon to display.
+ ///
+ public double FontSize { get; set; }
+
+ [ThreadStatic]
+ private static FontFamily segoeMDL2AssetsFontFamily;
+
+ ///
+ /// Gets the reusable "Segoe MDL2 Assets" instance.
+ ///
+ protected static FontFamily SegoeMDL2AssetsFontFamily
+ {
+ get => segoeMDL2AssetsFontFamily ??= new FontFamily("Segoe MDL2 Assets");
+ }
+
+ ///
+ /// Gets or sets the thickness of the icon glyph.
+ ///
+ public FontWeight FontWeight { get; set; } = FontWeights.Normal;
+
+ ///
+ /// Gets or sets the font style for the icon glyph.
+ ///
+ public FontStyle FontStyle { get; set; } = FontStyle.Normal;
+
+ ///
+ /// Gets or sets the foreground for the icon.
+ ///
+ public Brush Foreground { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether automatic text enlargement, to reflect the system text size setting, is enabled.
+ ///
+ public bool IsTextScaleFactorEnabled { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the icon is mirrored when the flow direction is right to left.
+ ///
+ public bool MirroredWhenRightToLeft { get; set; }
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/Abstract/TextIconExtension{T}.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/Abstract/TextIconExtension{T}.cs
new file mode 100644
index 00000000000..a7944e4058f
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/Abstract/TextIconExtension{T}.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.
+
+using Windows.UI.Xaml.Markup;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// An abstract which to produce text-based icons.
+ ///
+ /// The type representing the glyph for the current icon.
+ public abstract class TextIconExtension : TextIconExtension
+ {
+ ///
+ /// Gets or sets the value representing the icon to display.
+ ///
+ public T Glyph { get; set; }
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/BitmapIconExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/BitmapIconExtension.cs
new file mode 100644
index 00000000000..1c66370dbab
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/BitmapIconExtension.cs
@@ -0,0 +1,37 @@
+// 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 System;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// Custom which can provide values.
+ ///
+ [MarkupExtensionReturnType(ReturnType = typeof(BitmapIcon))]
+ public sealed class BitmapIconExtension : MarkupExtension
+ {
+ ///
+ /// Gets or sets the representing the image to display.
+ ///
+ public Uri Source { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to display the icon as monochrome.
+ ///
+ public bool ShowAsMonochrome { get; set; }
+
+ ///
+ protected override object ProvideValue()
+ {
+ return new BitmapIcon
+ {
+ ShowAsMonochrome = ShowAsMonochrome,
+ UriSource = Source
+ };
+ }
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconExtension.cs
new file mode 100644
index 00000000000..1e1c800d442
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconExtension.cs
@@ -0,0 +1,48 @@
+// 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 Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+using Windows.UI.Xaml.Media;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// Custom which can provide values.
+ ///
+ [MarkupExtensionReturnType(ReturnType = typeof(FontIcon))]
+ public class FontIconExtension : TextIconExtension
+ {
+ ///
+ /// Gets or sets the font family to use to display the icon. If , "Segoe MDL2 Assets" will be used.
+ ///
+ public FontFamily FontFamily { get; set; }
+
+ ///
+ protected override object ProvideValue()
+ {
+ var fontIcon = new FontIcon
+ {
+ Glyph = Glyph,
+ FontFamily = FontFamily ?? SegoeMDL2AssetsFontFamily,
+ FontWeight = FontWeight,
+ FontStyle = FontStyle,
+ IsTextScaleFactorEnabled = IsTextScaleFactorEnabled,
+ MirroredWhenRightToLeft = MirroredWhenRightToLeft
+ };
+
+ if (FontSize > 0)
+ {
+ fontIcon.FontSize = FontSize;
+ }
+
+ if (Foreground != null)
+ {
+ fontIcon.Foreground = Foreground;
+ }
+
+ return fontIcon;
+ }
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconSourceExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconSourceExtension.cs
new file mode 100644
index 00000000000..af2fe602587
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconSourceExtension.cs
@@ -0,0 +1,48 @@
+// 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 Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+using Windows.UI.Xaml.Media;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// Custom which can provide values.
+ ///
+ [MarkupExtensionReturnType(ReturnType = typeof(FontIconSource))]
+ public class FontIconSourceExtension : TextIconExtension
+ {
+ ///
+ /// Gets or sets the font family to use to display the icon. If , "Segoe MDL2 Assets" will be used.
+ ///
+ public FontFamily FontFamily { get; set; }
+
+ ///
+ protected override object ProvideValue()
+ {
+ var fontIcon = new FontIconSource
+ {
+ Glyph = Glyph,
+ FontFamily = FontFamily ?? SegoeMDL2AssetsFontFamily,
+ FontWeight = FontWeight,
+ FontStyle = FontStyle,
+ IsTextScaleFactorEnabled = IsTextScaleFactorEnabled,
+ MirroredWhenRightToLeft = MirroredWhenRightToLeft
+ };
+
+ if (FontSize > 0)
+ {
+ fontIcon.FontSize = FontSize;
+ }
+
+ if (Foreground != null)
+ {
+ fontIcon.Foreground = Foreground;
+ }
+
+ return fontIcon;
+ }
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/NullableBool.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/NullableBool.cs
index cb1831ea4ab..e3a5224dfa8 100644
--- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/NullableBool.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/NullableBool.cs
@@ -2,11 +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 System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Markup;
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/OnDevice.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/OnDevice.cs
index 21fdf480344..866a54383a1 100644
--- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/OnDevice.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/OnDevice.cs
@@ -2,7 +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 System;
using Windows.ApplicationModel;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Markup;
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/SymbolIconExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/SymbolIconExtension.cs
new file mode 100644
index 00000000000..414a33247c6
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/SymbolIconExtension.cs
@@ -0,0 +1,42 @@
+// 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 Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// Custom which can provide symbol-baased values.
+ ///
+ [MarkupExtensionReturnType(ReturnType = typeof(FontIcon))]
+ public class SymbolIconExtension : TextIconExtension
+ {
+ ///
+ protected override object ProvideValue()
+ {
+ var fontIcon = new FontIcon
+ {
+ Glyph = unchecked((char)Glyph).ToString(),
+ FontFamily = SegoeMDL2AssetsFontFamily,
+ FontWeight = FontWeight,
+ FontStyle = FontStyle,
+ IsTextScaleFactorEnabled = IsTextScaleFactorEnabled,
+ MirroredWhenRightToLeft = MirroredWhenRightToLeft
+ };
+
+ if (FontSize > 0)
+ {
+ fontIcon.FontSize = FontSize;
+ }
+
+ if (Foreground != null)
+ {
+ fontIcon.Foreground = Foreground;
+ }
+
+ return fontIcon;
+ }
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/SymbolIconSourceExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/SymbolIconSourceExtension.cs
new file mode 100644
index 00000000000..f5b4e1725da
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/SymbolIconSourceExtension.cs
@@ -0,0 +1,42 @@
+// 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 Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// Custom which can provide symbol-baased values.
+ ///
+ [MarkupExtensionReturnType(ReturnType = typeof(FontIconSource))]
+ public class SymbolIconSourceExtension : TextIconExtension
+ {
+ ///
+ protected override object ProvideValue()
+ {
+ var fontIcon = new FontIconSource
+ {
+ Glyph = unchecked((char)Glyph).ToString(),
+ FontFamily = SegoeMDL2AssetsFontFamily,
+ FontWeight = FontWeight,
+ FontStyle = FontStyle,
+ IsTextScaleFactorEnabled = IsTextScaleFactorEnabled,
+ MirroredWhenRightToLeft = MirroredWhenRightToLeft
+ };
+
+ if (FontSize > 0)
+ {
+ fontIcon.FontSize = FontSize;
+ }
+
+ if (Foreground != null)
+ {
+ fontIcon.Foreground = Foreground;
+ }
+
+ return fontIcon;
+ }
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
index 66345a6fa41..e6ef83568c6 100644
--- a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
+++ b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
@@ -2,6 +2,7 @@
uap10.0.16299
+ 8.0Windows Community Toolkit UI
This library provides UI components, such as XAML extensions, helpers, converters and more. It is part of the Windows Community Toolkit.
diff --git a/UnitTests/UnitTests.UWP/Extensions/Test_BitmapIconExtensionMarkupExtension.cs b/UnitTests/UnitTests.UWP/Extensions/Test_BitmapIconExtensionMarkupExtension.cs
new file mode 100644
index 00000000000..7eba199289f
--- /dev/null
+++ b/UnitTests/UnitTests.UWP/Extensions/Test_BitmapIconExtensionMarkupExtension.cs
@@ -0,0 +1,85 @@
+// 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 System;
+using System.Linq;
+using Microsoft.Toolkit.Uwp.UI.Extensions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+
+namespace UnitTests.Extensions
+{
+ [TestClass]
+ public class Test_BitmapIconExtensionMarkupExtension
+ {
+ [TestCategory("BitmapIconExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_BitmapIconExtension_MarkupExtension_ProvideImage()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("RootButton") as Button;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(Button)} control in tree.");
+
+ var item = ((MenuFlyout)button.Flyout)?.Items?.FirstOrDefault() as MenuFlyoutItem;
+
+ Assert.IsNotNull(button, $"Could not find the target {nameof(MenuFlyoutItem)} control.");
+
+ var icon = item.Icon as BitmapIcon;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(BitmapIcon)} element in button.");
+
+ Assert.AreEqual(icon.UriSource, new Uri("ms-resource:///Files/Assets/StoreLogo.png"), "Expected ms-resource:///Files/Assets/StoreLogo.png uri.");
+ Assert.AreEqual(icon.ShowAsMonochrome, false, "Expected icon not to be monochrome");
+ }
+
+ [TestCategory("BitmapIconExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_BitmapIconExtension_MarkupExtension_ProvideImageAndMonochrome()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("RootButton") as Button;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(Button)} control in tree.");
+
+ var item = ((MenuFlyout)button.Flyout)?.Items?.FirstOrDefault() as MenuFlyoutItem;
+
+ Assert.IsNotNull(button, $"Could not find the target {nameof(MenuFlyoutItem)} control.");
+
+ var icon = item.Icon as BitmapIcon;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(BitmapIcon)} element in button.");
+
+ Assert.AreEqual(icon.UriSource, new Uri("ms-resource:///Files/Assets/StoreLogo.png"), "Expected ms-resource:///Files/Assets/StoreLogo.png uri.");
+ Assert.AreEqual(icon.ShowAsMonochrome, true, "Expected icon to be monochrome");
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnitTests/UnitTests.UWP/Extensions/Test_FontIconExtensionMarkupExtension.cs b/UnitTests/UnitTests.UWP/Extensions/Test_FontIconExtensionMarkupExtension.cs
new file mode 100644
index 00000000000..a8b7465c587
--- /dev/null
+++ b/UnitTests/UnitTests.UWP/Extensions/Test_FontIconExtensionMarkupExtension.cs
@@ -0,0 +1,92 @@
+// 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 Windows.UI.Text;
+using Microsoft.Toolkit.Uwp.UI.Extensions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+
+namespace UnitTests.Extensions
+{
+ [TestClass]
+ public class Test_FontIconExtensionMarkupExtension
+ {
+ [TestCategory("FontIconExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_FontIconExtension_MarkupExtension_ProvideSegoeMdl2Asset()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("Check") as AppBarButton;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(AppBarButton)} control in tree.");
+
+ var icon = button.Icon as FontIcon;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(FontIcon)} element in button.");
+
+ Assert.AreEqual(icon.Glyph, "\uE105", "Expected icon glyph to be E105.");
+ Assert.AreEqual(icon.FontFamily.Source, "Segoe MDL2 Assets", "Expected font family to be Segoe MDL2 Assets");
+ }
+
+ [TestCategory("FontIconExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_FontIconExtension_MarkupExtension_ProvideSegoeUI()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("Check") as AppBarButton;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(AppBarButton)} control in tree.");
+
+ var icon = button.Icon as FontIcon;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(FontIcon)} element in button.");
+
+ Assert.AreEqual(icon.Glyph, "\uE14D", "Expected icon glyph to be E14D.");
+ Assert.AreEqual(icon.FontFamily.Source, "Segoe UI", "Expected font family to be Segoe UI");
+ }
+
+ [TestCategory("FontIconExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_FontIconExtension_MarkupExtension_ProvideCustomFontIcon()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("Check") as AppBarButton;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(AppBarButton)} control in tree.");
+
+ var icon = button.Icon as FontIcon;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(FontIcon)} element in button.");
+
+ Assert.AreEqual(icon.Glyph, "\uE14D", "Expected icon glyph to be E14D.");
+ Assert.AreEqual(icon.FontSize, 7.0, "Expected font size of 7");
+ Assert.AreEqual(icon.FontFamily.Source, "Segoe MDL2 Assets", "Expected font family to be Segoe MDL2 Assets");
+ Assert.AreEqual(icon.FontWeight, FontWeights.Bold, "Expected bold font weight");
+ Assert.AreEqual(icon.FontStyle, FontStyle.Italic, "Expected italic font style");
+ Assert.AreEqual(icon.IsTextScaleFactorEnabled, true, "Expected IsTextScaleFactorEnabled set to true");
+ Assert.AreEqual(icon.MirroredWhenRightToLeft, true, "Expected MirroredWhenRightToLeft set to true");
+ }
+ }
+}
diff --git a/UnitTests/UnitTests.UWP/Extensions/Test_FontIconSourceExtensionMarkupExtension.cs b/UnitTests/UnitTests.UWP/Extensions/Test_FontIconSourceExtensionMarkupExtension.cs
new file mode 100644
index 00000000000..0a35c561b15
--- /dev/null
+++ b/UnitTests/UnitTests.UWP/Extensions/Test_FontIconSourceExtensionMarkupExtension.cs
@@ -0,0 +1,113 @@
+// 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 System.Diagnostics.CodeAnalysis;
+using Windows.UI.Text;
+using Microsoft.Toolkit.Uwp.UI.Extensions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Markup;
+
+namespace UnitTests.Extensions
+{
+ [TestClass]
+ public class Test_FontIconSourceExtensionMarkupExtension
+ {
+ [TestCategory("FontIconSourceExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_FontIconSourceExtension_MarkupExtension_ProvideSegoeMdl2Asset()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("Check") as MockSwipeItem;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(MockSwipeItem)} control in tree.");
+
+ var icon = button.IconSource as FontIconSource;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(FontIcon)} element in button.");
+
+ Assert.AreEqual(icon.Glyph, "\uE105", "Expected icon glyph to be E105.");
+ Assert.AreEqual(icon.FontFamily.Source, "Segoe MDL2 Assets", "Expected font family to be Segoe MDL2 Assets");
+ }
+
+ [TestCategory("FontIconSourceExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_FontIconSourceExtension_MarkupExtension_ProvideSegoeUI()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("Check") as MockSwipeItem;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(MockSwipeItem)} control in tree.");
+
+ var icon = button.IconSource as FontIconSource;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(FontIcon)} element in button.");
+
+ Assert.AreEqual(icon.Glyph, "\uE14D", "Expected icon glyph to be E14D.");
+ Assert.AreEqual(icon.FontFamily.Source, "Segoe UI", "Expected font family to be Segoe UI");
+ }
+
+ [TestCategory("FontIconSourceExtensionMarkupExtension")]
+ [UITestMethod]
+ public void Test_FontIconSourceExtension_MarkupExtension_ProvideCustomFontIcon()
+ {
+ var treeroot = XamlReader.Load(@"
+
+") as FrameworkElement;
+
+ var button = treeroot.FindChildByName("Check") as MockSwipeItem;
+
+ Assert.IsNotNull(button, $"Could not find the {nameof(MockSwipeItem)} control in tree.");
+
+ var icon = button.IconSource as FontIconSource;
+
+ Assert.IsNotNull(icon, $"Could not find the {nameof(FontIcon)} element in button.");
+
+ Assert.AreEqual(icon.Glyph, "\uE14D", "Expected icon glyph to be E14D.");
+ Assert.AreEqual(icon.FontSize, 7.0, "Expected font size of 7");
+ Assert.AreEqual(icon.FontFamily.Source, "Segoe MDL2 Assets", "Expected font family to be Segoe MDL2 Assets");
+ Assert.AreEqual(icon.FontWeight, FontWeights.Bold, "Expected bold font weight");
+ Assert.AreEqual(icon.FontStyle, FontStyle.Italic, "Expected italic font style");
+ Assert.AreEqual(icon.IsTextScaleFactorEnabled, true, "Expected IsTextScaleFactorEnabled set to true");
+ Assert.AreEqual(icon.MirroredWhenRightToLeft, true, "Expected MirroredWhenRightToLeft set to true");
+ }
+ }
+
+ [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402", Justification = "Mock control for tests")]
+ public class MockSwipeItem : Control
+ {
+ public IconSource IconSource
+ {
+ get => (IconSource)GetValue(IconSourceProperty);
+ set => SetValue(IconSourceProperty, value);
+ }
+
+ public static readonly DependencyProperty IconSourceProperty =
+ DependencyProperty.Register(
+ nameof(IconSource),
+ typeof(IconSource),
+ typeof(MockSwipeItem),
+ new PropertyMetadata(default(IconSource)));
+ }
+}
\ No newline at end of file
diff --git a/UnitTests/UnitTests.UWP/Properties/UnitTestApp.rd.xml b/UnitTests/UnitTests.UWP/Properties/UnitTestApp.rd.xml
index 6e2afca77fe..be5c4987ee3 100644
--- a/UnitTests/UnitTests.UWP/Properties/UnitTestApp.rd.xml
+++ b/UnitTests/UnitTests.UWP/Properties/UnitTestApp.rd.xml
@@ -22,9 +22,19 @@
the application package. The asterisks are not wildcards.
-->
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UnitTests/UnitTests.UWP/UnitTestApp.xaml b/UnitTests/UnitTests.UWP/UnitTestApp.xaml
index c38cc7fbf26..f9e9631c047 100644
--- a/UnitTests/UnitTests.UWP/UnitTestApp.xaml
+++ b/UnitTests/UnitTests.UWP/UnitTestApp.xaml
@@ -1,5 +1,31 @@
+ xmlns:extensions="using:Microsoft.Toolkit.Uwp.UI.Extensions"
+ xmlns:unitTestExtensions="using:UnitTests.Extensions"
+ RequestedTheme="Light" >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
index 51c8d94a78d..4068af3426d 100644
--- a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
+++ b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
@@ -129,6 +129,9 @@
+
+
+